-
Notifications
You must be signed in to change notification settings - Fork 0
/
prune-branches
executable file
·43 lines (36 loc) · 1.48 KB
/
prune-branches
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
#! /bin/bash
# Prune worktrees
for worktree in $(git worktree list --porcelain | grep '^worktree' | sed 's/[^ ]* //' | tail -n +2); do
if [ -z "$(git -C "${worktree}" for-each-ref --contains)" ]; then
echo "Spared worktree ${worktree} (not merged)"
elif ! [ -z "$(git -C "${worktree}" status --porcelain)" ]; then
echo "Spared worktree ${worktree} (not clean)"
elif ! [ -z "$(lsof +D "${worktree}")" ]; then
echo "Spared worktree ${worktree} (open files)"
else
git worktree remove "${worktree}"
echo "Removed worktree ${worktree}"
fi
done
remote=origin
base_branch=master
# Prune branches
for branch_ref in $(git for-each-ref --format='%(refname)' 'refs/heads'); do
branch="$(git rev-parse --abbrev-ref "${branch_ref}")"
if ! [ -z "$(git for-each-ref --omit-empty --format='%(worktreepath)' "${branch_ref}")" ]; then
echo "Spared branch ${branch} (checked out)"
elif [ -z "$(git for-each-ref "${branch_ref}" --merged "${remote}/${base_branch}")" ]; then
echo "Spared branch ${branch} (not merged)"
else
git branch -D "${branch}"
fi
done
# Prune branches that have been squash-merged via PR
git for-each-ref refs/heads --shell --format '
gh pr list --state closed --base '"${base_branch}"' --search %(objectname) --json headRefOid | \
jq --raw-output ".[].headRefOid" | \
sed "s/^/git merge-base --is-ancestor %(objectname) /" | \
sed "s#\$# 2>/dev/null || \\\\#" | \
cat - <(echo false) | \
bash -e && echo %(refname:short)
' | bash | xargs git branch -D