-
Notifications
You must be signed in to change notification settings - Fork 0
/
gh-rm-merged
executable file
·98 lines (84 loc) · 3.59 KB
/
gh-rm-merged
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
#!/bin/bash
source "$(dirname "$0")/lib/common.sh"
if ! git diff --stat &>/dev/null ; then
err "Not in a git repo."
fi
if git diff --stat | grep -q . ; then
err "Repo is dirty. Can't rm branch."
fi
expected_remote="$(gh repo view --json owner,name | jq -r '"[email protected]:" + .owner.login + "/" + .name + ".git"')"
actual_remote="$(git remote -v | tr ' ' $'\t' | cut -f 2 | sort -u)"
if [[ "$(wc -l <<< "$actual_remote" )" -ne 1 ]]; then
msg "Multiple remotes found. I don't know how to handle that smartly, so this may not work. Will try anyway."
elif [[ "$actual_remote" != "$expected_remote" ]]; then
msg "Remote is $actual_remote, but GitHub knows it as $expected_remote."
msg "This means we won't be able to find the pull requests."
msg "Run:"
err " git remote set-url origin $expected_remote"
fi
default_branch_name="$(gh repo view --json defaultBranchRef | jq -r .defaultBranchRef.name)"
curr_branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ "$curr_branch" == HEAD ]]; then
err "Dir is in detached state. Can't rm (there's no branch name to rm)."
fi
function check_and_rm {
branch_name="$1"
if [[ "$branch_name" == "$default_branch_name" ]]; then
msg "Can't rm $default_branch_name because it is this repo's default branch."
return 1
fi
last_sha="$(git log -n 1 --pretty=format:%H "$branch_name")"
merged_into_json="$(gh pr list -S "$last_sha" --state merged --json baseRefName,url)"
# The index takes some time to update, so it may not be available as "--state merged" for a few minutes.
# So, if we don't find it there, search again without the flag.
if [[ "$(<<<"$merged_into_json" jq length)" == 0 ]]; then
merged_into_json="$(gh pr list -S "$last_sha" --state merged --json baseRefName,url,state)"
merged_into_json="$(<<<"$merged_into_json" jq 'map(select(.state == "MERGED"))')"
fi
# Ignore any PRs *into* this branch.
echo ===========================
# why do we want this?
# I think DON'T want it if $branch_name is a feature branch, and the PR was for another branch into this one.
# But in that case, you can git checkout the feature branch, then do "gh-rm-merged <other branch>" and it seems to work.
# So maybe this is fine?
# Lol what am i even doing
merged_into_json="$(echo "$merged_into_json" | jq '[ .[] | select(.baseRefName != $curr) ]' --arg curr "$branch_name")"
case "$(<<<"$merged_into_json" jq length)" in
""|0)
err "No merged PRs found for the latest commit ($branch_name@${last_sha:0:8}). Can't rm branch."
;;
1)
;; # Desired case!
*)
msg "Multiple merged PRs found for the latest commit ($branch_name@${last_sha:0:8}):"
echo "$merged_into_json" | jq -r '.[]| "• " + .url + " into " + .baseRefName'
err "Can't rm branch. If one of those branches is the one you wanted to merge into, you can safely delete this branch."
;;
esac
merged_into="$(<<<"$merged_into_json" jq -r '.[].baseRefName')"
pr_url="$(<<<"$merged_into_json" jq -r '.[].url')"
msg "Merged into $merged_into via $pr_url"
git co "$merged_into"
git branch -D "$branch_name"
git pull
if [[ "$branch_name" != "$curr_branch" ]]; then
git co "$curr_branch" # move back to where we were
fi
}
if [[ $# -lt 1 ]]; then
check_and_rm "$curr_branch"
else
exit_code=0
for branch_name in "$@"; do
if ! check_and_rm "$branch_name" ; then
exit_code=1
fi
done
if [[ "$exit_code" != 0 ]]; then
exit "$exit_code"
fi
fi
# We only get here if the above check_and_rm(s) didn't error
msg '──────────────────────────'
msg "git branches:"
>&2 git branch