summaryrefslogtreecommitdiffstats
path: root/resources/com/google/gerrit/server/tools/root/bin/gerrit-cherry-pick
diff options
context:
space:
mode:
Diffstat (limited to 'resources/com/google/gerrit/server/tools/root/bin/gerrit-cherry-pick')
-rw-r--r--resources/com/google/gerrit/server/tools/root/bin/gerrit-cherry-pick208
1 files changed, 208 insertions, 0 deletions
diff --git a/resources/com/google/gerrit/server/tools/root/bin/gerrit-cherry-pick b/resources/com/google/gerrit/server/tools/root/bin/gerrit-cherry-pick
new file mode 100644
index 0000000000..7a414c8b35
--- /dev/null
+++ b/resources/com/google/gerrit/server/tools/root/bin/gerrit-cherry-pick
@@ -0,0 +1,208 @@
+#!/bin/sh
+#
+# Part of Gerrit Code Review (https://www.gerritcodereview.com/)
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+usage() {
+ echo >&2 "usage: $0 remote changeid..."
+ echo >&2 "usage: $0 --continue"
+ echo >&2 "usage: $0 --skip"
+ echo >&2 "usage: $0 --abort"
+ echo >&2 "usage: $0 [--close|--replace] remote"
+ exit 1
+}
+
+die() {
+ echo >&2 "fatal: $1"
+ exit 1
+}
+
+GIT_DIR=$(git rev-parse --git-dir) || exit
+CL="$GIT_DIR/GERRIT_CHANGES"
+STATE="$GIT_DIR/rebase-gerrit"
+TODO="$STATE/todo"
+
+RESOLVEMSG="
+When you have resolved this problem run \"$0 --continue\".
+If you would prefer to skip this patch, run \"$0 --skip\".
+"
+
+pop_action() {
+ sed -e 1d <"$TODO" >>"$TODO".new
+ mv -f "$TODO".new "$TODO"
+}
+
+mark_done() {
+ read commit changeid <"$TODO"
+ changeid=$(get_changeid "$changeid")
+ head_after=$(git rev-parse HEAD^0)
+ head_before=$(cat "$STATE/head_before")
+ if ! test $head_after = $head_before
+ then
+ echo $head_after >"$CL/$changeid"
+ fi
+ pop_action
+}
+
+do_next() {
+ while test -s "$TODO"
+ do
+ read commit changeid <"$TODO"
+ git rev-parse HEAD^0 >"$STATE/head_before"
+ git format-patch \
+ -k --stdout --full-index --ignore-if-in-upstream \
+ $commit^..$commit |
+ git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" || exit
+ mark_done
+ done
+
+ echo >&2 "Done."
+ rm -rf "$STATE"
+}
+
+git_am_opt=
+if test -f "$STATE/git_am_opt"
+then
+ git_am_opt=$(cat "$STATE/git_am_opt")
+fi
+
+while test $# != 0
+do
+ case "$1" in
+ --continue)
+ test -f "$TODO" || die "No cherry-pick in progress?"
+ git am $git_am_opt --rebasing --resolvemsg="$RESOLVEMSG" --resolved || exit
+ mark_done
+ do_next
+ exit
+ ;;
+ --skip)
+ test -f "$TODO" || die "No cherry-pick in progress?"
+ git reset --hard HEAD || exit
+ git am --skip || exit
+ pop_action
+ do_next
+ exit
+ ;;
+ --abort)
+ test -f "$TODO" || die "No cherry-pick in progress?"
+ git reset --hard HEAD
+ git am --skip
+ rm -rf "$STATE"
+ ;;
+ --close|--replace)
+ shift
+ test -d "$CL" || die "No changes to close"
+ test $# = 1 || usage
+ remote=$1
+ printf %s "git push $remote" >&2
+ rs=$(cd "$CL" && for change_id in *; do
+ test "$change_id" = '*' && die "No changes to close"
+ c=$(cat "$change_id");
+ echo "$c:refs/changes/$change_id";
+ echo ' \' >&2;
+ printf %s " $c:refs/changes/$change_id" >&2
+ done)
+ echo >&2
+ echo >&2
+ git push $remote $rs
+ rc=$?
+ test $rc = 0 && rm -rf "$CL"
+ exit $rc
+ ;;
+ --whitespace=*)
+ git_am_opt="$git_am_opt $1"
+ ;;
+ --committer-date-is-author-date|--ignore-date)
+ git_am_opt="$git_am_opt $1"
+ ;;
+ -C*)
+ git_am_opt="$git_am_opt $1"
+ ;;
+ -s|--signoff)
+ git_am_opt="$git_am_opt $1"
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+get_changeid() {
+ case $1 in
+ */*) echo ${1%%/*} ;;
+ *) echo $1 ;;
+ esac
+}
+
+to_ref() {
+ case $1 in
+ */*)
+ change_id=${1%%/*}
+ patchset_id=${1##*/}
+ ;;
+ *)
+ change_id=$1
+ patchset_id=1
+ ;;
+ esac
+
+ hash=$(($change_id % 100))
+ case $hash in
+ [0-9]) hash="0$hash" ;;
+ esac
+
+ echo "refs/changes/$hash/$change_id/$patchset_id"
+}
+
+get_revid() {
+ grep $(to_ref $1) <"$GIT_DIR/FETCH_HEAD" | cut -f1
+}
+
+# Initialize state
+#
+test $# -lt 2 && usage
+remote="$1"
+shift
+
+mkdir "$STATE" || die "cherry-pick already in progress"
+echo $git_am_opt >"$STATE/git_am_opt"
+
+if ! git fetch $remote $(for id; do to_ref $id; done)
+then
+ rm -rf $STATE
+ exit 1
+fi
+
+(for id
+ do
+ if revid=$(get_revid $id)
+ then
+ echo "$revid $id"
+ else
+ echo >&2 "fatal: $id not found"
+ exit 1
+ fi
+done) >"$TODO"
+
+mkdir -p "$CL"
+echo >&2
+do_next