Read more

Git: removing feature branches on merge

Dominik Schöler
August 24, 2022Software engineer at makandra GmbH

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.

Illustration online protection

Rails professionals since 2007

Our laser focus on a single technology has made us a leader in this space. Need help?

  • We build a solid first version of your product
  • We train your development team
  • We rescue your project in trouble
Read more Show archive.org snapshot

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
August 24, 2022Software engineer at makandra GmbH
Posted by Dominik Schöler to makandra dev (2022-08-24 07:40)