Repository navigation
Expand file tree
/
Copy pathpr-number
More file actions
executable file
·86 lines (77 loc) · 2.77 KB
/
Copy pathpr-number
File metadata and controls
executable file
·86 lines (77 loc) · 2.77 KB
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
#!/bin/sh
# Print the number of the GitHub pull request whose head is the current branch.
# Works whether the pull request is within one repository or is from a fork to
# the fork's parent repository, and whether or not the branch that the pull
# request was made from is the one that the local branch tracks.
# With --url, prints the pull request's URL instead of its number.
set -eu
field=number
if [ "${1:-}" = "--url" ]; then
field=url
shift
fi
if [ $# -ne 0 ]; then
echo "Usage: pr-number [--url]" >&2
exit 2
fi
branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch" = "HEAD" ]; then
echo "pr-number: detached HEAD, no branch to look up" >&2
exit 1
fi
# The pushed branch name can differ from the local branch name.
if upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2> /dev/null); then
remote=${upstream%%/*}
head_branch=${upstream#*/}
else
remote=origin
head_branch=$branch
fi
# Append a word to a space-separated list, if the list does not contain it.
# Arguments: the current list, the word. Prints the new list.
add_word() {
case " $1 " in
*" $2 "*) printf '%s' "$1" ;;
*) printf '%s' "${1:+$1 }$2" ;;
esac
}
# The same branch may exist in several of the repositories that this clone has
# remotes for, and the pull request may have been made from any of them. Search
# every remote's repository, plus the parent of each that is a fork, starting
# with the repository of the remote that the branch tracks.
# Resolving from each remote's URL avoids gh's base-repo guessing.
repos=
owners=
for r in "$remote" $(git remote | grep -v -x "$remote"); do
if ! remote_url=$(git remote get-url "$r" 2> /dev/null); then
continue
fi
if ! repo_json=$(gh repo view "$remote_url" --json nameWithOwner,parent 2> /dev/null); then
continue
fi
for repo in \
$(printf '%s' "$repo_json" \
| jq -r '.nameWithOwner, (if .parent then .parent.owner.login + "/" + .parent.name else empty end)'); do
repos=$(add_word "$repos" "$repo")
owners=$(add_word "$owners" "${repo%%/*}")
done
done
if [ -z "$repos" ]; then
echo "pr-number: no GitHub repository found among this clone's remotes" >&2
exit 1
fi
# gh does not accept the "owner:branch" form for --head, so match the head
# repository's owner afterward. Otherwise a same-named branch in an unrelated
# fork could be reported.
for repo in $repos; do
result=$(gh pr list --repo "$repo" --head "$head_branch" --state all \
--json "$field",headRepositoryOwner \
| jq -r --arg owners "$owners" --arg field "$field" \
'[.[] | select(.headRepositoryOwner.login as $o | $owners | split(" ") | index($o)) | .[$field]] | first // empty')
if [ -n "$result" ]; then
echo "$result"
exit 0
fi
done
echo "pr-number: no pull request found for branch $head_branch in $repos" >&2
exit 1