Git: removing feature branches on merge

Updated . Posted . Visible to the public. Repeats.

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
Dominik Schöler
Last edit
Daniel Straßner
License
Source code in this card is licensed under the MIT License.
Posted by Dominik Schöler to makandra dev (2022-08-24 05:40)