-
-
Notifications
You must be signed in to change notification settings - Fork 54
/
Copy pathpick-to-branch
executable file
·148 lines (130 loc) · 3.76 KB
/
pick-to-branch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#! /usr/bin/env bash
function usage {
echo "Usage: pick-to-branch [<id> | h | HEAD ] <target> [<num>]
Cherry-pick a commit (or <num> commits) on the given target release branch.
If this is not the current branch, the current branch and its state are preserved.
The optional <id> arg specifies the ID of the (last) commit to cherry-pick.
It can also be given in the form of a branch name. If 'h' or 'HEAD'
or no <id> arg is given, the commit id of the HEAD of the master is used.
The <target> arg must match a release branch or start with 'm' for master.
A release branch may be given simply as 102, 110, 111, 30, 31.
The optional <num> argument specifies the number of commits to cherry-pick.
It defaults to 1 and can be specified only in case <id> is also given."
}
num=1
case $# in
3)
id=$1
b=$2
num=$3
;;
2)
id=$1
b=$2
;;
1)
id=`git show -s --format="%H" master`
b=$1
;;
*)
usage
exit 1
;;
esac
case $id in
h|HEAD) id=`git show -s --format="%H" master`;;
esac
case $b in
*1*0*2*)
TARGET=OpenSSL_1_0_2-stable
;;
*1*1*1*)
TARGET=OpenSSL_1_1_1-stable
;;
*3*0*)
TARGET=openssl-3.0
;;
*3*1*)
TARGET=openssl-3.1
;;
*3*2*)
TARGET=openssl-3.2
;;
*3*3*)
TARGET=openssl-3.3
;;
*3*4*)
TARGET=openssl-3.4
;;
m*)
TARGET=master
;;
*)
echo Unknown target release branch \'$b\'
exit 1
;;
esac
REMOTE=$(git for-each-ref --format='%(push:remotename)' \
$(git rev-parse --symbolic-full-name $TARGET))
# usually this will be 'upstream'
if [ "$REMOTE" = "" ] ; then
echo Cannot find git remote for target branch $TARGET
exit 1
fi
git remote get-url $REMOTE | grep -q 'github.openssl.org:' \
|| echo -e "WARNING: URL of remote '$REMOTE' of target branch '$TARGET' does not match 'github.openssl.org'\n"
echo "Target remote and branch is: $REMOTE/$TARGET"
echo "First commit to cherry-pick is: $id~$((num - 1))"
echo "Number of commits to pick: $num"
echo
echo "Commit(s) to be cherry-picked:"
git log $id~$num..$id
echo
echo -n "Press Enter to continue, Ctrl-C to abort: "; read foo
ORIG_REF=`git rev-parse --abbrev-ref HEAD` # usually this will be 'master'
if [ "$TARGET" != "$ORIG_REF" ]; then
STASH_OUT=`git stash`
fi
function cleanup {
rv=$?
echo # make sure to enter new line, needed, e.g., after Ctrl-C
[ $rv -ne 0 ] && echo -e "pick-to-branch failed"
if [ "$CHERRYPICKING" == 1 ] ; then
echo "cherry-picking failed - maybe did not provide a suitable <num> argument?"
git cherry-pick --abort 2>/dev/null || true
fi
if [ "$ORIG_TARGET_HEAD" != "" ]; then
echo Restoring original commit HEAD of $TARGET
git reset --merge "$ORIG_TARGET_HEAD"
fi
if [ "$TARGET" != "$ORIG_REF" ]; then
echo Returning to previous branch $ORIG_REF
git checkout -q $ORIG_REF
if [ "$STASH_OUT" != "No local changes to save" ]; then
git stash pop -q # restore original state, pruning any leftover commits added locally
fi
fi
}
set -o errexit
trap 'cleanup' EXIT
git checkout --quiet master
git checkout $TARGET
ORIG_TARGET_HEAD=`git show -s --format="%H"`
git pull --ff-only `git rev-parse --abbrev-ref @{u} | sed "s|/| |"`
CHERRYPICKING=1
git cherry-pick -e -x $id~$num..$id || (echo -ne "Press Ctrl-d to abort, or fix the issue in another shell,\n run 'git cherry-pick --continue' there, and on success press Enter here: "; read || exit 1)
CHERRYPICKING=
echo
while true ; do
echo -n "Enter 'y'/'yes' to push or 'n'/'no' to abort: "
read x
x="`echo $x | tr A-Z a-z`"
if [ "$x" = "y" -o "$x" = "yes" -o "$x" = "n" -o "$x" = "no" ]
then
break
fi
done
if [ "$x" = "y" -o "$x" = "yes" ] ; then
git push
ORIG_TARGET_HEAD=
fi