-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathgit-hub-pr
274 lines (236 loc) · 7.58 KB
/
git-hub-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
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
264
265
266
267
268
269
270
271
272
273
274
#!/usr/bin/env bash
command:pr-new() {
require-auth
get-args "?number:'none'"
local owner="$(get-owner)"
local repo="$(get-repo)"
assert-inside-git-repo
assert-repo-top-level
assert-git-repo-is-clean
get-default-remote-name
get-branch-name
get-parent-remote-name
get-parent-owner-repo
get-parent-base
git fetch "$remote_name" "$branch_name" &> /dev/null ||
abort "Can't fetch remote='$remote_name' branch='$branch_name' (did you push it?)"
if [[ $(git rev-parse $branch_name) != $(git rev-parse $remote_name/$branch_name) ]]; then
abort "Branch $branch_name is not in sync with branch $remote_name/$branch_name";
fi
git fetch "$parent_remote_name" "$parent_base" &> /dev/null ||
abort "Can't fetch parent remote='$parent_remote_name' branch='$parent_base'"
local diff="$(git diff $parent_remote_name/$parent_base..$branch_name)"
if [[ -z $diff ]]; then
abort "No changes between $parent_remote_name/$parent_base and $branch_name."
fi
local head="$owner:$branch_name"
local base="$parent_base"
local url="/repos/$parent_owner_repo/pulls"
if [[ $number =~ ^[0-9]+$ ]]; then
local prompt_msg="Attach PR $owner/$repo:$branch_name -> $parent_owner_repo:$parent_base to issue #$number? [yN]"
local doit=$(prompt "$prompt_msg")
if [[ $doit =~ ^[yY] ]]; then
api-post "$url" "$(
json-dump-object head "$head" base "$base" issue "$number"
)"
msg_ok="Attached PR to issue: $(JSON.get -s /html_url -)"
else
msg_ok=0
fi
else
editor-title-body "
# New GitHub Pull Request
#
# Requesting that...
# repo: $owner/$repo
# branch: $branch_name
# ...be pulled into...
# repo: $parent_owner_repo
# branch: $parent_base
#
# Enter your pull request info at the top like this:
#
# First line is the pull request subject
#
# The pull request body comes here, after a blank line separating it from
# the subject.
#
# The body can be as many lines as needed, and is optional. Only the pull
# request subject is required.
#
#------------------------------------------------------------------------------
$ git diff $parent_remote_name/$parent_base..$branch_name
$diff
#------------------------------------------------------------------------------
$ git log $parent_remote_name/$parent_base..$branch_name
$(git log $parent_remote_name/$parent_base..$branch_name)
"
api-post "$url" "$(
json-dump-object head "$head" base "$base" title "$title" body "$body"
)"
if OK; then
msg_ok="New PR created: $(JSON.get -a /html_url -)"
else
msg_fail="New PR failed: $(JSON.get -a /errors/0/message -)"
fi
fi
}
command:pr-list() {
get-args '?owner:get-user/repo:get-repo'
state=open
"$do_all" && state=all
title="Pull requests for '$owner/$repo' (state=$state):"
report-list \
"/repos/$owner/$repo/pulls?state=$state;sort=updated;direction=desc;per_page=PER_PAGE" \
'number state title user/login created_at updated_at head/label base/label html_url draft'
}
format-entry:pr-list() {
local number=$2 state=$3 title=$4 creator=$5 created=$6 updated=$7
local head=$8 base=$9 url=${10} draft=${11} statecolor=YELLOW
if "$raw_output"; then
local repo=$url
repo="${url#https\:\/\/github\.com\/}"
repo="${repo%\/pull\/[[:digit:]]*}"
printf "$repo\t$number\n"
else
if $draft; then
state="$state/draft"
statecolor=DARKGRAY
fi
color-table-row \
"#%-3d" LABEL "$number" \
"%-8s" $statecolor "($state)" \
"" "" "$title"
color-table-row \
" @%-12s" LOGIN "$creator" \
"" "" "Created: " \
"" DATE "${created/T*}" \
"" "" "Updated:" \
"%s" DATE "${updated/T*}"
color-table-row \
" %s" "" "$head → $base"
fi
}
command:pr-diff() {
get-args '?owner:get-owner/repo:get-repo' number
api-get "/repos/$owner/$repo/pulls/$number"
}
ok:pr-diff() {
head_url="$(JSON.get -s /head/repo/ssh_url -)"
head_sha="$(JSON.get -s /head/sha -)"
head_ref="$(JSON.get -s /head/ref -)"
git fetch "$head_url" "$head_ref" &> /dev/null
base_url="$(JSON.get -s /base/repo/ssh_url -)"
base_sha="$(JSON.get -s /base/sha -)"
base_ref="$(JSON.get -s /base/ref -)"
git fetch "$base_url" "$base_ref" &> /dev/null
git diff "$base_sha" "$head_sha"
}
command:pr-fetch() {
get-args '?owner:get-owner/repo:get-repo' number
assert-inside-git-repo
if [[ -n $(git branch | grep -E "^PR/$number$") ]]; then
echo "Branch PR/$number already exists"
else
git fetch -f "[email protected]:$owner/$repo" "refs/pull/$number/head:PR/$number" ||
error "can't fetch PR $number"
fi
msg_ok=0
}
command:pr-fetch-fork() {
local pr_user pr_branch fork_url
get-args '?owner:get-owner/repo:get-repo' number
assert-inside-git-repo
api-get "/repos/$owner/$repo/pulls/$number"
pr_user=$(JSON.get -s /user/login -)
pr_branch=$(JSON.get -s /head/ref -)
fork_url=$(JSON.get -s /head/repo/ssh_url -)
if [[ -n $(git remote | grep -E "^$pr_user$") ]]; then
echo "Remote $pr_user already exists"
else
git remote add "$pr_user" "$fork_url" ||
error "can't add remote $pr_user $fork_url"
fi
full_branch=$pr_user/$pr_branch
if [[ -n $(git branch | grep -E "^$full_branch$") ]]; then
echo "Branch $full_branch already exists"
else
git fetch "$pr_user" "$pr_branch" ||
error "can't fetch PR $full_branch"
fi
say "Fetched PR $number into $full_branch"
msg_ok=0
}
command:pr-merge() {
get-args '?owner:get-owner/repo:get-repo' number '?message'
local json_list=()
if [[ -n "$commit_sha" ]]; then
json_list=("${json_list[@]}" "sha" "$commit_sha")
fi
if [[ -n "$merge_method" ]]; then
json_list=("${json_list[@]}" "merge_method" "$merge_method")
fi
if [[ -n "$commit_title" ]]; then
json_list=("${json_list[@]}" "commit_title" "$commit_title")
fi
if [[ -n "$commit_message" ]]; then
json_list=("${json_list[@]}" "commit_message" "$commit_message")
fi
IFS='' json="$( json-dump-object ${json_list[*]} )"
api-put "/repos/$owner/$repo/pulls/$number/merge" "$json"
}
command:pr-queue() {
local search_uri='/search/issues?q=type:pr+$state+user:$user;per_page=PER_PAGE'
pr-search-query "$@"
}
command:pr-created() {
local search_uri='/search/issues?q=type:pr+$state+author:$user;per_page=PER_PAGE'
pr-search-query "$@"
}
command:pr-involves() {
local search_uri='/search/issues?q=type:pr+$state+involves:$user;per_page=PER_PAGE'
pr-search-query "$@"
}
pr-search-query() {
get-args '?user:get-user'
local state="state:open";
"$do_all" && state=""
local key_prefix=/items
local search_fields="number state title user/login created_at updated_at html_url"
search_uri="${search_uri/\$user/$user}"
search_uri="${search_uri/\$state/$state}"
report-list "$search_uri" "$search_fields"
}
format-entry:pr-queue() {
_list-pr-queue "$@"
}
format-entry:pr-created() {
_list-pr-queue "$@"
}
format-entry:pr-involves() {
_list-pr-queue "$@"
}
_list-pr-queue() {
local number=$2 state=$3 title=$4 creator=$5 created=$6 updated=$7 url=$8
local repo=$url
repo="${url#https\:\/\/github\.com\/}"
repo="${repo%\/pull\/[[:digit:]]*}"
if "$raw_output"; then
printf "$repo\t$number\n"
else
echo "$(colorize REPO "$repo" )"
color-table-row \
"#%-3d" LABEL "$number" \
"%-8s" YELLOW "($state)" \
"" "" "$title"
color-table-row \
" @%-12s" LOGIN "$creator" \
"" "" "Created:" \
"" DATE "${created/T*/}" \
"" "" " Updated:" \
"" DATE "${updated/T*/}"
color-table-row \
" %s" "" "$url"
fi
}
# vim: set ft=sh lisp: