git
is a popular version control system for code.
git branch --merged | grep -P -v "(^\*|master|main)" | xargs git branch -d
The above will not work for multi-commit branches that are merged via Github “squash + merge” on a PR.
The typical workflow is:
dev
branchdev
branch (same name)dev
branch –> main
branchdev
branchmain
dev
branch :(The local dev
branch doesn’t look like it’s merged because it’s commit hash
is not present in the main
log due to the squash.
git fetch -p
branches=$(git for-each-ref --format '%(refname) %(upstream:track)' refs/heads | awk '$2 == "[gone]" {sub("refs/heads/", "", $1); print $1}')
for branch in $branches;
do
git branch -D $branch
done
git prune origin
Source: Remove tracking branches no longer on remote
git remote prune origin \
| git branch -a \
| grep -v HEAD \
| sed 's/remotes\/origin\///g' \
| sed 's/^\*/ /g' \
| sort \
| uniq --count \
| grep -P "^\s+1\s+" \
| awk '{print $2}' \
| xargs -p -L 1 git branch -D
Explanation: Calls git branch -D
on any local branch not present on origin.
git remote prune origin
: deletes local trackers for branches deleted on origingit branch -a
: show all tracked branchesgrep -v HEAD
: ignore the HEAD trackersed 's/remotes\/origin\///g'
: remove the remotes/origin
prefix on the remote trackerssed 's/^\*/ /g'
: remove the asterisk used to show current branchsort
: sort the linesuniq --count
: count the number of times each branch name shows upgrep -P "^\s+1\s+"
: filter down to the branches which only occur once (local-only!)awk '{print $2}'
: filter out the countsxargs -p -L 1 git branch -D
:
-L 1
: for each line of output (branch name)-P
: print delete branch command and request y/n promptgit branch -D
: delete the branchThis involves less complexity
# Remove remote/* branches tracked locally that have been deleted on origin.
git remote prune origin
# Show all branches tracked locally
git branch -a
# Force delete any branches which do not have a remote/* version
git branch -D $FOO