When working with feature branches, stale branches pile up over time. It's best to remove them right after merge, locally and on the remote, but it is a little tedious: you need to remember it, and perform the few steps manually each time.
Enter Git hooks. The folks at Liquid Light have built a little post-merge hook that will delete a feature branch on confirmation Show archive.org snapshot .
Quick aside: Git hooks location
Git hooks are normally stored in the current repository, at .git/hooks/
. (Note they are not checked in and will not be shared with others!)
If you prefer to manage your hooks globally, i.e. have a single set of hooks that applies to all your repositories, you can
change the Git hooks location
Show archive.org snapshot
: git config --global core.hooksPath /path/to/my/centralized/hooks
.
The post-merge hook
Create a post-merge
file in your hooks directory (see above). Paste this:
#!/bin/bash
exec < /dev/tty
# Get the current branch name
branch_name=$(git branch --show-current)
# Get the name of the branch that was just merged
reflog_message=$(git reflog -1)
merged_branch_name=$(echo $reflog_message | cut -d" " -f 4 | sed "s/://")
if [[ "$merged_branch_name" == "@{-1}" ]]; then
# Somebody merged "-", the previous branch. Resolve it to the actual branch
# name.
merged_branch_name=$(git name-rev @{-1} --name-only)
fi
# Don't offer branch deletion for some branch names
if [[ "$merged_branch_name" =~ ^(master|main|production|Fast-forward)$ ]]; then
exit 0
fi
# Begin output
echo " "
echo "You have just merged the branch \"$merged_branch_name\" into \"$branch_name\". "
# Ask the question
read -p "Do you want to delete the \"$merged_branch_name\" branch? (y/N) " answer
# Check if the answer is a single lowercase Y
if [[ "$answer" == "y" ]]; then
# Delete the local branch
echo "Deleting local branch \"$merged_branch_name\" ..."
git branch -d $merged_branch_name
# Delete the remote branch
echo "Deleting remote branch ..."
git push origin --delete $merged_branch_name
exit 1
else
echo "Did not delete the \"$merged_branch_name\" branch."
fi
Save the file and make it executable: chmod +x path/to/post-merge
Now, after merging a branch, you will be asked if you would like to have the branch deleted:
$ git merge ds/foo
Updating 338e82e38..2d4269c81
Fast-forward
foo | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 foo
You have just merged the branch "ds/foo" into "master".
Do you want to delete the "ds/foo" branch? (y/N) y
Deleting local branch "ds/foo" ...
Deleted branch ds/foo (was 2d4269c81).
Deleting remote branch ...
- [deleted] ds/foo
Optional: Ask if the main branch should be pushed before deletion of the feature branch
Github and Gitlab mark a pull request as closed if the corresponding branch is deleted. If you want the pull request to be listed as "merged" instead, you have to push the main branch before deleting the merged feature branch.
You can add the following snippet to the hook (before the script asks if the merged branch should be deleted):
read -p "Do you want to push the \"$branch_name\" branch? (y/N) " answer
if [[ "$answer" == "y" ]]; then
echo "Pushing the \"$branch_name\" branch ..."
git push origin $branch_name
else
echo "Did not push the \"$branch_name\" branch."
fi