-
Notifications
You must be signed in to change notification settings - Fork 722
/
g
executable file
·163 lines (143 loc) · 5.13 KB
/
g
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
#!/bin/bash -e
#
# './g pull -r' just forwards to 'git pull -r'.
#
# './g review [name]' to submit a pull request, assuming:
# 1) You have 'gh' installed.
# 2) You are a committer, so you have the permission to push to a private/nick/name branch.
# 3) You delete this branch after the PR is merged.
# 4) "name" is the name of part of the private/user/name remote branch, defaults to the current
# branch. You have to specify this explicitly if you want to update an existing PR.
#
# './g backport <branch> <PR number> [name]' to submit a pull request for a different branch:
# 1) Checks out a local branch for the remote <branch>.
# 2) Cherry-picks commits from <PR number>
# 3) Uses './g review' to submit a pull request against <branch>.
#
# not_in_standard_branches $BRANCH $REMOTE
not_in_standard_branches() {
# e.g., with $1 = co-4-2, and $2 = origin
# check for origin/co-4-2 branch
if git rev-parse --quiet --verify $2/$1 >/dev/null; then
return 1 # indicate failure - there's a top-level branch named that way
fi
# check for origin/distro/*/co-4-2 branches
local distro_branch
for distro_branch in $(git branch --remotes --list "$2/distro/*/$1"); do
return 2 # indicate failure - there's a distro branch named that way
done
return 0
}
if [ -z "$(type -p gh)" ]; then
echo "'gh' not found, install it from <https://github.com/cli/cli/blob/trunk/docs/install_linux.md>."
exit 1
fi
if ! gh auth status &>/dev/null; then
echo "'gh' thinks you are not logged into any GitHub hosts. Run 'gh auth login' to authenticate."
exit 1
fi
# e.g. co-4-2
BRANCH=$(git symbolic-ref HEAD|sed 's|refs/heads/||')
# e.g. origin
REMOTE=$(git config branch.$BRANCH.remote)
if [ "$1" == "review" ]; then
# e.g. distro/collabora/co-4-2
TRACKED_BRANCH=$(git rev-parse --abbrev-ref --symbolic-full-name HEAD@{upstream}|sed "s|${REMOTE}/||")
REMOTE_BRANCH=private/$USER/$TRACKED_BRANCH
CUSTOM_BRANCH=
if [ -n "$2" ]; then
REMOTE_BRANCH=private/$USER/$2
CUSTOM_BRANCH=y
elif [ "$TRACKED_BRANCH" != "$BRANCH" ]; then
if not_in_standard_branches "$BRANCH" "$REMOTE"; then
# there's no top-level or distro-specific remote branch named as local branch: use its name
REMOTE_BRANCH=private/$USER/$BRANCH
CUSTOM_BRANCH=y
fi
fi
# So that we have an up to date view on what remote branches exist.
git fetch --prune $REMOTE
HAS_REMOTE_BRANCH=
if git rev-parse --quiet --verify $REMOTE/$REMOTE_BRANCH >/dev/null; then
HAS_REMOTE_BRANCH=y
fi
if [ -n "$HAS_REMOTE_BRANCH" ] && [ -z "$CUSTOM_BRANCH" ]; then
echo "Error: default remote branch would be '$REMOTE_BRANCH', but it already exists."
# Use $TRACKED_BRANCH, because we push to $REMOTE_BRANCH, which derives from
# $TRACKED_BRANCH, not $BRANCH.
echo "To update the existing PR: type './g review $TRACKED_BRANCH' explicitly."
exit 1
elif [ -n "$HAS_REMOTE_BRANCH" ] && [ -n "$CUSTOM_BRANCH" ]; then
# PR is open, same branch is explicitly specified, just update it.
git push -f $REMOTE HEAD:$REMOTE_BRANCH
else
# Open a new PR.
git push $REMOTE HEAD:$REMOTE_BRANCH
git branch $REMOTE_BRANCH
gh pr create --base $TRACKED_BRANCH --head $REMOTE_BRANCH --fill
git branch -D $REMOTE_BRANCH
fi
exit 0
fi
if [ "$1" == "backport" ]; then
if [ -z "$(type -p jq)" ]; then
echo "'jq' not found, install it with your package manager."
exit 1
fi
BACKPORT_BRANCH=$2
if [ -z "$BACKPORT_BRANCH" ]; then
echo "Error: backport branch is not specified"
echo "Usage: './g backport <branch> <PR number> [name]'"
echo "Example: './g backport distro/collabora/co-6-4 42'"
exit 1
fi
if ! git rev-parse --quiet --verify $REMOTE/$BACKPORT_BRANCH >/dev/null; then
echo "Error: backport branch does not exist"
exit 1
fi
PRNUM=$3
if [ -z "$PRNUM" ]; then
echo "Error: PR number is not specified"
exit 1
fi
# Optional.
CUSTOM_BRANCH=$4
JSON=$(mktemp)
gh api graphql --field owner=":owner" --field repo=":repo" -f query='
query($owner: String!, $repo: String!)
{
repository(owner: $owner, name: $repo)
{
pullRequest(number: '$PRNUM')
{
baseRefOid
headRefOid
}
}
}' > $JSON
BASE_COMMIT=$(cat $JSON | jq --raw-output ".data.repository.pullRequest.baseRefOid")
HEAD_COMMIT=$(cat $JSON | jq --raw-output ".data.repository.pullRequest.headRefOid")
rm $JSON
COMMIT_RANGE=$BASE_COMMIT..$HEAD_COMMIT
# Create local branch if needed.
BRANCH_CREATED=
if git rev-parse --quiet --verify master2 >/dev/null; then
git checkout $BACKPORT_BRANCH
else
git checkout --track $REMOTE/$BACKPORT_BRANCH
BRANCH_CREATED=y
fi
git cherry-pick $COMMIT_RANGE
$0 review $CUSTOM_BRANCH
git checkout $BRANCH
if [ -n "$BRANCH_CREATED" ]; then
git branch -D $BACKPORT_BRANCH
fi
exit 0
fi
if [ "$1" == "pull" ]; then
shift
git pull "$@"
exit 0
fi
# vim:set shiftwidth=4 softtabstop=4 expandtab: