]> Git Repo - VerusCoin.git/blob - contrib/devtools/github-merge.sh
print the caught error instead of raising an error
[VerusCoin.git] / contrib / devtools / github-merge.sh
1 #!/bin/bash
2
3 # This script will locally construct a merge commit for a pull request on a
4 # github repository, inspect it, sign it and optionally push it.
5
6 # The following temporary branches are created/overwritten and deleted:
7 # * pull/$PULL/base (the current master we're merging onto)
8 # * pull/$PULL/head (the current state of the remote pull request)
9 # * pull/$PULL/merge (github's merge)
10 # * pull/$PULL/local-merge (our merge)
11
12 # In case of a clean merge that is accepted by the user, the local branch with
13 # name $BRANCH is overwritten with the merged result, and optionally pushed.
14
15 REPO="$(git config --get githubmerge.repository)"
16 if [[ "d$REPO" == "d" ]]; then
17   echo "ERROR: No repository configured. Use this command to set:" >&2
18   echo "git config githubmerge.repository <owner>/<repo>" >&2
19   echo "In addition, you can set the following variables:" >&2
20   echo "- githubmerge.host (default [email protected])" >&2
21   echo "- githubmerge.branch (default master)" >&2
22   echo "- githubmerge.testcmd (default none)" >&2
23   exit 1
24 fi
25
26 HOST="$(git config --get githubmerge.host)"
27 if [[ "d$HOST" == "d" ]]; then
28   HOST="[email protected]"
29 fi
30
31 BRANCH="$(git config --get githubmerge.branch)"
32 if [[ "d$BRANCH" == "d" ]]; then
33   BRANCH="master"
34 fi
35
36 TESTCMD="$(git config --get githubmerge.testcmd)"
37
38 PULL="$1"
39
40 if [[ "d$PULL" == "d" ]]; then
41   echo "Usage: $0 pullnumber [branch]" >&2
42   exit 2
43 fi
44
45 if [[ "d$2" != "d" ]]; then
46   BRANCH="$2"
47 fi
48
49 # Initialize source branches.
50 git checkout -q "$BRANCH"
51 if git fetch -q "$HOST":"$REPO" "+refs/pull/$PULL/*:refs/heads/pull/$PULL/*"; then
52   if ! git log -q -1 "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then
53     echo "ERROR: Cannot find head of pull request #$PULL on $HOST:$REPO." >&2
54     exit 3
55   fi
56   if ! git log -q -1 "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then
57     echo "ERROR: Cannot find merge of pull request #$PULL on $HOST:$REPO." >&2
58     exit 3
59   fi
60 else
61   echo "ERROR: Cannot find pull request #$PULL on $HOST:$REPO." >&2
62   exit 3
63 fi
64 if git fetch -q "$HOST":"$REPO" +refs/heads/"$BRANCH":refs/heads/pull/"$PULL"/base; then
65   true
66 else
67   echo "ERROR: Cannot find branch $BRANCH on $HOST:$REPO." >&2
68   exit 3
69 fi
70 git checkout -q pull/"$PULL"/base
71 git branch -q -D pull/"$PULL"/local-merge 2>/dev/null
72 git checkout -q -b pull/"$PULL"/local-merge
73 TMPDIR="$(mktemp -d -t ghmXXXXX)"
74
75 function cleanup() {
76   git checkout -q "$BRANCH"
77   git branch -q -D pull/"$PULL"/head 2>/dev/null
78   git branch -q -D pull/"$PULL"/base 2>/dev/null
79   git branch -q -D pull/"$PULL"/merge 2>/dev/null
80   git branch -q -D pull/"$PULL"/local-merge 2>/dev/null
81   rm -rf "$TMPDIR"
82 }
83
84 # Create unsigned merge commit.
85 (
86   echo "Merge pull request #$PULL"
87   echo ""
88   git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head
89 )>"$TMPDIR/message"
90 if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then
91   if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then
92     echo "ERROR: Creating merge failed (already merged?)." >&2
93     cleanup
94     exit 4
95   fi
96 else
97   echo "ERROR: Cannot be merged cleanly." >&2
98   git merge --abort
99   cleanup
100   exit 4
101 fi
102
103 # Run test command if configured.
104 if [[ "d$TESTCMD" != "d" ]]; then
105   # Go up to the repository's root.
106   while [ ! -d .git ]; do cd ..; done
107   if ! $TESTCMD; then
108     echo "ERROR: Running $TESTCMD failed." >&2
109     cleanup
110     exit 5
111   fi
112   # Show the created merge.
113   git diff pull/"$PULL"/merge..pull/"$PULL"/local-merge >"$TMPDIR"/diff
114   git diff pull/"$PULL"/base..pull/"$PULL"/local-merge
115   if [[ "$(<"$TMPDIR"/diff)" != "" ]]; then
116     echo "WARNING: merge differs from github!" >&2
117     read -p "Type 'ignore' to continue. " -r >&2
118     if [[ "d$REPLY" =~ ^d[iI][gG][nN][oO][rR][eE]$ ]]; then
119       echo "Difference with github ignored." >&2
120     else
121       cleanup
122       exit 6
123     fi
124   fi
125   read -p "Press 'd' to accept the diff. " -n 1 -r >&2
126   echo
127   if [[ "d$REPLY" =~ ^d[dD]$ ]]; then
128     echo "Diff accepted." >&2
129   else
130     echo "ERROR: Diff rejected." >&2
131     cleanup
132     exit 6
133   fi
134 else
135   # Verify the result.
136   echo "Dropping you on a shell so you can try building/testing the merged source." >&2
137   echo "Run 'git diff HEAD~' to show the changes being merged." >&2
138   echo "Type 'exit' when done." >&2
139   bash -i
140   read -p "Press 'm' to accept the merge. " -n 1 -r >&2
141   echo
142   if [[ "d$REPLY" =~ ^d[Mm]$ ]]; then
143     echo "Merge accepted." >&2
144   else
145     echo "ERROR: Merge rejected." >&2
146     cleanup
147     exit 7
148   fi
149 fi
150
151 # Sign the merge commit.
152 read -p "Press 's' to sign off on the merge. " -n 1 -r >&2
153 echo
154 if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then
155   if [[ "$(git config --get user.signingkey)" == "" ]]; then
156     echo "WARNING: No GPG signing key set, not signing. Set one using:" >&2
157     echo "git config --global user.signingkey <key>" >&2
158     git commit -q --signoff --amend --no-edit
159   else
160     git commit -q --gpg-sign --amend --no-edit
161   fi
162 fi
163
164 # Clean up temporary branches, and put the result in $BRANCH.
165 git checkout -q "$BRANCH"
166 git reset -q --hard pull/"$PULL"/local-merge
167 cleanup
168
169 # Push the result.
170 read -p "Type 'push' to push the result to $HOST:$REPO, branch $BRANCH. " -r >&2
171 if [[ "d$REPLY" =~ ^d[Pp][Uu][Ss][Hh]$ ]]; then
172   git push "$HOST":"$REPO" refs/heads/"$BRANCH"
173 fi
This page took 0.034342 seconds and 4 git commands to generate.