... | ... |
@@ -176,6 +176,36 @@ OpenShift is checked into this repository. To install `godep` locally run: |
176 | 176 |
|
177 | 177 |
If you are not updating packages you should not need godep installed. |
178 | 178 |
|
179 |
+## Cherry-picking an upstream commit into Origin |
|
180 |
+ |
|
181 |
+You can use `hack/cherry-pick.sh` to generate patches for Origin from upstream commits. To use |
|
182 |
+this command, be sure to setup remote branches like https://gist.github.com/piscisaureus/3342247 |
|
183 |
+so that `git show origin/pr/<number>` displays information about your branch after a `git fetch`. |
|
184 |
+You must also have the Kubernetes repository checked out in your GOPATH (visible as `../../../k8s.io/kubernetes`) |
|
185 |
+and have no modified or uncommited files in either repository. |
|
186 |
+ |
|
187 |
+To pull an upstream commit, run: |
|
188 |
+ |
|
189 |
+ $ hack/cherry-pick.sh <pr_number> |
|
190 |
+ |
|
191 |
+This will attempt to create a patch from the current Kube rebase version in Origin that contains |
|
192 |
+the commits added in the PR. If the PR has already been merged to the Kube version, you'll get an |
|
193 |
+error. If there are conflicts, you'll have to resolve them in the upstream repo, then hit ENTER |
|
194 |
+to continue. The end result will be a single commit in your Origin repo that contains the changes. |
|
195 |
+ |
|
196 |
+If you want to run without a rebase option, set `NO_REBASE=1` before the command is run. You can |
|
197 |
+also specify a commit range directly with: |
|
198 |
+ |
|
199 |
+ $ hack/cherry-pick.sh origin/master...<some_branch> |
|
200 |
+ |
|
201 |
+All upstream commits should have a commit message where the first line is: |
|
202 |
+ |
|
203 |
+ UPSTREAM: <PR number|drop|carry>: <short description> |
|
204 |
+ |
|
205 |
+`drop` indicates the commit should be removed during the next rebase. `carry` means that the change |
|
206 |
+cannot go into upstream, and we should continue to use it during the next rebase. |
|
207 |
+ |
|
208 |
+ |
|
179 | 209 |
## Updating Kubernetes from upstream |
180 | 210 |
|
181 | 211 |
There are a few steps involved in rebasing Origin to a new version of Kubernetes. We need to make sure |
182 | 212 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,83 @@ |
0 |
+#!/bin/bash |
|
1 |
+ |
|
2 |
+# See HACKING.md for usage |
|
3 |
+ |
|
4 |
+set -o errexit |
|
5 |
+set -o nounset |
|
6 |
+set -o pipefail |
|
7 |
+ |
|
8 |
+OS_ROOT=$(dirname "${BASH_SOURCE}")/.. |
|
9 |
+source "${OS_ROOT}/hack/common.sh" |
|
10 |
+source "${OS_ROOT}/hack/util.sh" |
|
11 |
+os::log::install_errexit |
|
12 |
+ |
|
13 |
+# Go to the top of the tree. |
|
14 |
+cd "${OS_ROOT}" |
|
15 |
+ |
|
16 |
+if [[ "$#" -ne 1 ]]; then |
|
17 |
+ echo "You must supply a pull request by number or a Git range in the upstream Kube project" 1>&2 |
|
18 |
+ exit 1 |
|
19 |
+fi |
|
20 |
+os::build::require_clean_tree # Origin tree must be clean |
|
21 |
+ |
|
22 |
+patch="${TMPDIR}/patch" |
|
23 |
+kubedir="../../../k8s.io/kubernetes" |
|
24 |
+if [[ ! -d "${kubedir}" ]]; then |
|
25 |
+ echo "Expected ${kubedir} to exist" 1>&2 |
|
26 |
+ exit 1 |
|
27 |
+fi |
|
28 |
+ |
|
29 |
+if [[ -z "${NO_REBASE-}" ]]; then |
|
30 |
+ lastkube="$(go run ${OS_ROOT}/hack/version.go ${OS_ROOT}/Godeps/Godeps.json k8s.io/kubernetes/pkg/api)" |
|
31 |
+fi |
|
32 |
+ |
|
33 |
+pushd "${kubedir}" > /dev/null |
|
34 |
+os::build::require_clean_tree |
|
35 |
+git fetch |
|
36 |
+ |
|
37 |
+selector="$(os::build::commit_range $1 origin/master)" |
|
38 |
+ |
|
39 |
+if [[ -z "${NO_REBASE-}" ]]; then |
|
40 |
+ echo "++ Generating patch for ${selector} onto ${lastkube} ..." 2>&1 |
|
41 |
+ if git rev-parse kube_rebaser_branch > /dev/null 2>&1; then |
|
42 |
+ git branch -d kube_rebaser_branch |
|
43 |
+ fi |
|
44 |
+ git checkout -b kube_rebaser_branch "${lastkube}" |
|
45 |
+ git diff -p --raw "${selector}" > "${patch}" |
|
46 |
+ if ! git apply -3 "${patch}"; then |
|
47 |
+ git rerere # record pre state |
|
48 |
+ echo 2>&1 |
|
49 |
+ echo "++ Merge conflicts when generating patch, please resolve conflicts and then press ENTER to continue" 1>&2 |
|
50 |
+ read |
|
51 |
+ fi |
|
52 |
+ git rerere # record post state |
|
53 |
+ # stage any new files |
|
54 |
+ git add . > /dev/null |
|
55 |
+ # construct a new patch |
|
56 |
+ git diff --cached -p --raw --{src,dst}-prefix=a/Godeps/_workspace/src/k8s.io/kubernetes/ > "${patch}" |
|
57 |
+ # cleanup the current state |
|
58 |
+ git reset HEAD --hard > /dev/null |
|
59 |
+ git checkout master > /dev/null |
|
60 |
+ git branch -d kube_rebaser_branch > /dev/null |
|
61 |
+else |
|
62 |
+ echo "++ Generating patch for ${selector} without rebasing ..." 2>&1 |
|
63 |
+ git diff -p --raw --{src,dst}-prefix=a/Godeps/_workspace/src/k8s.io/kubernetes/ "${selector}" > "${patch}" |
|
64 |
+fi |
|
65 |
+ |
|
66 |
+popd > /dev/null |
|
67 |
+ |
|
68 |
+echo "++ Applying patch ..." 2>&1 |
|
69 |
+echo 2>&1 |
|
70 |
+set +e |
|
71 |
+git apply --reject "${patch}" |
|
72 |
+if [[ $? -ne 0 ]]; then |
|
73 |
+ echo "++ Not all patches applied, merge *.req into your files or rerun with REBASE=1" |
|
74 |
+ exit 1 |
|
75 |
+fi |
|
76 |
+ |
|
77 |
+set -o errexit |
|
78 |
+git add . |
|
79 |
+git commit -m "UPSTREAM: $1: " > /dev/null |
|
80 |
+git commit --amend |
|
81 |
+echo 2>&1 |
|
82 |
+echo "++ Done" 2>&1 |
... | ... |
@@ -510,6 +510,46 @@ os::build::ldflags() { |
510 | 510 |
) |
511 | 511 |
} |
512 | 512 |
|
513 |
+# os::build::require_clean_tree exits if the current Git tree is not clean. |
|
514 |
+os::build::require_clean_tree() { |
|
515 |
+ if ! git diff-index --quiet HEAD -- || test $(git ls-files --exclude-standard --others | wc -l) != 0; then |
|
516 |
+ echo "You can't have any staged or dirty files in $(pwd) for this command." |
|
517 |
+ echo "Either commit them or unstage them to continue." |
|
518 |
+ exit 1 |
|
519 |
+ fi |
|
520 |
+} |
|
521 |
+ |
|
522 |
+# os::build::commit_range takes one or two arguments - if the first argument is an |
|
523 |
+# integer, it is assumed to be a pull request and the local origin/pr/# branch is |
|
524 |
+# used to determine the common range with the second argument. If the first argument |
|
525 |
+# is not an integer, it is assumed to be a Git commit range and output directly. |
|
526 |
+os::build::commit_range() { |
|
527 |
+ if [[ "$1" =~ ^-?[0-9]+$ ]]; then |
|
528 |
+ local target |
|
529 |
+ target="$(git rev-parse origin/pr/$1)" |
|
530 |
+ if [[ $? -ne 0 ]]; then |
|
531 |
+ echo "Branch does not exist, or you have not configured origin/pr/* style branches from GitHub" 1>&2 |
|
532 |
+ exit 1 |
|
533 |
+ fi |
|
534 |
+ |
|
535 |
+ local base |
|
536 |
+ base="$(git merge-base origin/pr/$1 $2)" |
|
537 |
+ if [[ $? -ne 0 ]]; then |
|
538 |
+ echo "Branch has no common commits with $2" 1>&2 |
|
539 |
+ exit 1 |
|
540 |
+ fi |
|
541 |
+ if [[ "${base}" == "${target}" ]]; then |
|
542 |
+ echo "Branch has already been merged to upstream master, use explicit range instead" 1>&2 |
|
543 |
+ exit 1 |
|
544 |
+ fi |
|
545 |
+ |
|
546 |
+ echo "${base}...${target}" |
|
547 |
+ exit 0 |
|
548 |
+ fi |
|
549 |
+ |
|
550 |
+ echo "$1" |
|
551 |
+} |
|
552 |
+ |
|
513 | 553 |
os::build::gen-docs() { |
514 | 554 |
local cmd="$1" |
515 | 555 |
local dest="$2" |