Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ghmerge « review-tools - github.com/openssl/tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 00de102dacc255b40ea6dd098ba5832ee76a0aae (plain)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#! /bin/bash

function usage_exit {
    >&2 echo "Usage: ghmerge <options including prnum and reviewer(s)>
    or ghmerge [<options>] -- <prnum> <reviewer>...
Options may include addrev options and gitaddrev filter args.

Option style arguments:

--help              Print this help and exit
--tools             Merge a tools PR (rather than openssl PR)
--web               Merge a web PR (rather than openssl PR)
--remote <remote>   Repo to merge with (rather than git.openssl.org), usually 'upstream'
--ref <branch>      Branch to merge with (rather than current branch), usually 'master'
--cherry-pick       Use cherry-pick (rather than pull --rebase)
--squash            Squash new commits non-interactively (allows editing msg)
--noautosquash      Do not automatically squash fixups in interactive rebase
--nobuild           Do not call 'openssbuild' before merging

Examples:

  ghmerge 12345 mattcaswell
  ghmerge 12345 paulidale t8m --nobuild --myemail=dev@ddvo.net
  ghmerge edd05b7^^^^..19692bb2c32 --squash -- 12345 levitte
  ghmerge 12345 slontis --ref openssl-3.0"
    exit 9
}

set -o errexit

WHAT=""
PICK=no
INTERACTIVE=yes
AUTOSQUASH="--autosquash"
REMOTE=""
REF=""
BUILD=yes
[ -z ${CC+x} ] && CC="ccache gcc" # opensslbuild will otherwise use "ccache clang-3.6"

if [ ! -d .git ] ; then
    echo Not at a top-level git directory
    exit 1
fi

PRNUM=
TEAM=""
ADDREVOPTS=""
# Parse JCL.
shopt -s extglob
while [ $# -ne 0 ]; do
    case "$1" in
    --help)
        usage_exit
        ;;
    --tools)
        WHAT=tools ; BUILD=no ; shift
        ;;
    --web)
        WHAT=web ; BUILD=no ; shift
        ;;
    --cherry-pick)
        PICK=yes ; shift
        ;;
    --noautosquash)
        AUTOSQUASH="" ; shift
        ;;
    --squash)
        INTERACTIVE=no ; shift
        ;;
    --nobuild)
        BUILD=no ; shift
        ;;
    --remote)
        if [ $# -lt 2 ] ; then
            echo "Missing argument of '$1'"
            usage_exit
        fi
        shift; REMOTE=$1; shift
        ;;
    --ref)
        if [ $# -lt 2 ] ; then
            echo "Missing argument of '$1'"
            usage_exit
        fi
        shift; REF=$1; shift
        ;;
    --)
        if [ $# -lt 3 ] ; then
            echo "Missing <prnum> <reviewer>... after '--'"
            usage_exit
        fi
        shift; PRNUM=$1 ; shift
        TEAM="$TEAM $*"
        break
        ;;
    -*) # e.g., --verbose, --trivial, --myemail=...
        ADDREVOPTS="$ADDREVOPTS $1"
        shift
        ;;
    +([[:digit:]]) ) # e.g., 1453
        PRNUM=$1; shift
        ;;
    @*) # e.g., @t8m
        TEAM="$TEAM $1"; shift
        ;;
    +([[:alnum:]-]) ) # e.g., levitte
        if [[ $1 =~ ^[0-9a-f]{7,}+$ ]]; then # e.g., edd05b7
            ADDREVOPTS="$ADDREVOPTS $1"
        else
            TEAM="$TEAM $1"
        fi
        shift
        ;;
    *) # e.g., edd05b7^^^^..19692bb2c32
        ADDREVOPTS="$ADDREVOPTS $1"; shift
        ;;
    esac
done

if [ "$WHAT" = "" ] ; then
    WHAT="openssl"
else
    ADDREVOPTS="$ADDREVOPTS --$WHAT"
fi
ADDREVOPTS=${ADDREVOPTS# } # chop any leading ' '

[ "$REMOTE" = "" ] && REMOTE=`git remote -v | awk '/git.openssl.org.*(push)/{ print $1; }' | head -n 1` # usually this will be 'upstream'
if [ "$REMOTE" = "" ] ; then
    echo Cannot find git remote with URL including 'git.openssl.org'
    exit 1
fi

if [ "$PRNUM" = "" -o "$TEAM" = "" ] ; then
    usage_exit
fi

PR_URL=https://api.github.com/repos/openssl/$WHAT/pulls/$PRNUM
if ! wget --quiet $PR_URL -O /tmp/gh$$; then
    echo "Error getting $PR_URL"
    exit 1
fi
set -- `python -c '
from __future__ import print_function
import json, sys;
input = json.load(sys.stdin)
print(str(input["head"]["label"]).replace(":", " "),
      str(input["head"]["repo"]["ssh_url"]))'        </tmp/gh$$`
WHO=$1
BRANCH=$2
REPO=$3
rm /tmp/gh$$

if [ -z "$WHO" -o -z "$BRANCH" -o -z "$REPO" ]; then
    echo "Could not determine from $PR_URL which branch of whom to fetch from where"
    exit 1
fi

ORIG_REF=`git rev-parse --abbrev-ref HEAD` # usually this will be 'master'
STASH_OUT=`git stash`
WORK="copy-of-${WHO}-${BRANCH}"

(git branch | grep -q "$WORK") && (echo "Branch already exists: $WORK"; exit 1)

function cleanup {
    rv=$?
    echo # make sure to enter new line, needed, e.g., after Ctrl-C
    [ $rv -ne 0 ] && echo -e "\nghmerge failed"
    if [ "$REBASING" == 1 ] ; then
        git rebase --abort 2>/dev/null || true
    fi
    if [ "$CHERRYPICKING" == 1 ] ; then
        echo "Hint: maybe --cherry-pick was not given a suitable <n> parameter."
        git cherry-pick --abort 2>/dev/null || true
    fi
    if [ "$REF" != "$ORIG_REF" ] || [ "$WORK_USED" != "" ]; then
        echo Returning to previous branch $ORIG_REF
        git checkout -q $ORIG_REF
    fi
    if [ "$WORK_USED" != "" ]; then
        git branch -qD $WORK_USED
    fi
    if [ "$STASH_OUT" != "No local changes to save" ]; then
        git stash pop -q # restore original state, pruning any leftover commits added locally
    fi
}
trap 'cleanup' EXIT

[ "$REF" = "" ] && REF=$ORIG_REF
if [ "$REF" != "$ORIG_REF" ]; then    
    echo -n "Press Enter to checkout $REF: "; read foo
    git checkout $REF
fi

echo -n "Press Enter to pull the latest $REMOTE/$REF: "; read foo
REBASING=1
git pull $REMOTE $REF || exit 1
REBASING=

WORK_USED=$WORK
# append new commits from $REPO/$BRANCH
if [ "$PICK" != "yes" ]; then
    echo Rebasing $REPO/$BRANCH on $REF...
    git fetch $REPO $BRANCH && git checkout -b $WORK FETCH_HEAD
    WORK_USED=$WORK
    REBASING=1
    git rebase $REF || (echo 'Fix or Ctrl-d to abort' ; read || exit 1)
    REBASING=
else
    echo Cherry-picking $REPO/$BRANCH to $REF...
    git checkout -b $WORK $REF
    WORK_USED=$WORK
    CHERRYPICKING=1
    git fetch $REPO $BRANCH && (git cherry-pick FETCH_HEAD || exit 1)
    CHERRYPICKING=
fi

echo Diff against $REMOTE/$REF
git diff $REMOTE/$REF

if [ "$INTERACTIVE" == "yes" ] ; then
    echo -n "Press Enter to interactively rebase $AUTOSQUASH on $REMOTE/$REF: "; read foo
    REBASING=1
    git rebase -i $AUTOSQUASH $REMOTE/$REF || exit 1
    REBASING=
    echo "Calling addrev $ADDREVOPTS --prnum=$PRNUM $TEAM $REMOTE/$REF.."
    addrev $ADDREVOPTS --prnum=$PRNUM $TEAM $REMOTE/$REF..
fi

echo Log since $REMOTE/$REF
git log $REMOTE/$REF..

git checkout $REF
if [ "$INTERACTIVE" != "yes" ] ; then
    echo -n "Press Enter to non-interactively merge --squash $BRANCH to $REMOTE/$REF: "; read foo
    git merge --ff-only --no-commit --squash $WORK
    AUTHOR=`git show --no-patch --pretty="format:%an <%ae>" $WORK`
    git commit --author="$AUTHOR"
    addrev $ADDREVOPTS --prnum=$PRNUM $TEAM $REMOTE/${REF}..
else
    # echo -n "Press Enter to merge to $REMOTE/$REF: "; read foo
    git merge --ff-only $WORK
fi

echo New log since $REMOTE/$REF
git log $REMOTE/$REF..

if [ "$BUILD" == "yes" ] ; then
    echo Rebuilding...
    CC="$CC" opensslbuild >/dev/null # any STDERR output will be shown
fi

while true ; do
    echo -n "Enter 'y'/'yes' to push to $REMOTE/$REF 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 -v $REMOTE $REF
fi