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 branchmaindev 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