forked from npm/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpr
executable file
·167 lines (145 loc) · 3.96 KB
/
pr
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
#!/usr/bin/env bash
# Land a pull request
# Creates a PR-### branch, pulls the commits, opens up an interactive rebase to
# squash, and then annotates the commit with the changelog goobers
#
# Usage:
# pr <url|number> [<upstream remote>=origin]
main () {
if [ "$1" = "finish" ]; then
shift
finish "$@"
return $?
fi
local url="$(prurl "$@")"
local num=$(basename $url)
local prpath="${url#[email protected]:}"
local repo=${prpath%/pull/$num}
local prweb="https://github.com/$prpath"
local root="$(prroot "$url")"
local api="https://api.github.com/repos/${repo}/pulls/${num}"
local user=$(curl -s $api | json user.login)
local ref="$(prref "$url" "$root")"
local curhead="$(git show --no-patch --pretty=%H HEAD)"
local curbranch="$(git rev-parse --abbrev-ref HEAD)"
local cleanlines
IFS=$'\n' cleanlines=($(git status -s -uno))
if [ ${#cleanlines[@]} -ne 0 ]; then
echo "working dir not clean" >&2
IFS=$'\n' echo "${cleanlines[@]}" >&2
echo "aborting PR merge" >&2
fi
# ok, ready to rock
branch=PR-$num
if [ "$curbranch" == "$branch" ]; then
echo "already on $branch, you're on your own" >&2
return 1
fi
me=$(git config github.user || git config user.name)
if [ "$me" == "" ]; then
echo "run 'git config --add github.user <username>'" >&2
return 1
fi
exists=$(git show --no-patch --pretty=%H $branch 2>/dev/null)
if [ "$exists" == "" ]; then
git fetch origin pull/$num/head:$branch
git checkout $branch
else
git checkout $branch
git pull --rebase origin pull/$num/head
fi
git rebase -i $curbranch # squash and test
if [ $? -eq 0 ]; then
finish "${curbranch}"
else
echo "resolve conflicts and run: $0 finish "'"'${curbranch}'"'
fi
}
# add the PR-URL to the last commit, after squashing
finish () {
if [ $# -eq 0 ]; then
echo "Usage: $0 finish <branch> (while on a PR-### branch)" >&2
return 1
fi
local curbranch="$1"
local ref=$(cat .git/HEAD)
local prnum
case $ref in
"ref: refs/heads/PR-"*)
prnum=${ref#ref: refs/heads/PR-}
;;
*)
echo "not on the PR-## branch any more!" >&2
return 1
;;
esac
local me=$(git config github.user || git config user.name)
if [ "$me" == "" ]; then
echo "run 'git config --add github.user <username>'" >&2
return 1
fi
set -x
local url="$(prurl "$prnum")"
local num=$prnum
local prpath="${url#[email protected]:}"
local repo=${prpath%/pull/$num}
local prweb="https://github.com/$prpath"
local root="$(prroot "$url")"
local api="https://api.github.com/repos/${repo}/pulls/${num}"
local user=$(curl -s $api | json user.login)
local lastmsg="$(git log -1 --pretty=%B)"
local newmsg="${lastmsg}
PR-URL: ${prweb}
Credit: @${user}
Close: #${num}
Reviewed-by: @${me}
"
git commit --amend -m "$newmsg"
git checkout $curbranch
git merge PR-${prnum} --ff-only
set +x
}
prurl () {
local url="$1"
if [ "$url" == "" ] && type pbpaste &>/dev/null; then
url="$(pbpaste)"
fi
if [[ "$url" =~ ^[0-9]+$ ]]; then
local us="$2"
if [ "$us" == "" ]; then
us="origin"
fi
local num="$url"
local o="$(git config --get remote.${us}.url)"
url="${o}"
url="${url#(git:\/\/|https:\/\/)}"
url="${url#git@}"
url="${url#github.com[:\/]}"
url="${url%.git}"
url="https://github.com/${url}/pull/$num"
fi
url=${url%/commits}
url=${url%/files}
url="$(echo $url | perl -p -e 's/#issuecomment-[0-9]+$//g')"
local p='^https:\/\/github.com\/[^\/]+\/[^\/]+\/pull\/[0-9]+$'
if ! [[ "$url" =~ $p ]]; then
echo "Usage:"
echo " $0 <pull req url>"
echo " $0 <pull req number> [<remote name>=origin]"
type pbpaste &>/dev/null &&
echo "(will read url/id from clipboard if not specified)"
exit 1
fi
url="${url/https:\/\/github\.com\//[email protected]:}"
echo "$url"
}
prroot () {
local url="$1"
echo "${url/\/pull\/+([0-9])/}"
}
prref () {
local url="$1"
local root="$2"
echo "refs${url:${#root}}/head"
}
main "$@"