This script fast forward merges a branch and then deletes the old one. I normally run it like this:

git m master feature

Here's a link to the gist.

#!/bin/bash -x
set -e

#by naming this git-m and putting it in your PATH, git will be able to run it when you type "git m ..."

if [ "$#" -ne 2 ]
  echo "Wrong number of arguments. Should be 2, was $#";
  exit 1;

git checkout $1;
git merge --ff-only $2;
git branch -d $2;

Is there anything wrong with this? My biggest fear is I could run this script with a typo and end up deleting a branch without merging first.


3 Answers 3


Two minor notes:

  1. You can restore a deleted branches with the reflog (although reflog entries can expire).

  2. I would check at the beginning whether the feature ($2) branch exists or not. In the latter case do not checkout the master ($1) branch nor modify the state of the working copy, just print an error message.

  • \$\begingroup\$ How would you do #2? \$\endgroup\$ Jun 29, 2014 at 0:07
  • 2
    \$\begingroup\$ @tieTYT: Um, I've just found this one: stackoverflow.com/q/5167957/843804 \$\endgroup\$
    – palacsint
    Jun 29, 2014 at 0:19
  • \$\begingroup\$ I ended up using git show-branch $2 || (echo "$2 is not an exiting branch" && exit 1); \$\endgroup\$ Jun 29, 2014 at 2:24

The order of the arguments is backwards, I think. Compare against git-rebase(1):


git rebase [<upstream>] [<branch>]


If <branch> is specified, git rebase will perform an automatic git checkout <branch> before doing anything else. Otherwise it remains on the current branch.

The git-rebase order is also better since the git checkout can be considered optional. You should probably make yours optional as well.

The help message needs to be much more informative about what the command does and how to use it. Git is hard enough to use as it is.

Accidental branch deletion is unlikely to be tragic, since you used -d and not -D.

  • \$\begingroup\$ Yeah @DavidHarkness mentioned the order, too. I think I'm going to leave it that way. I gave my reason in a comment to his answer. \$\endgroup\$ Jun 29, 2014 at 4:07

Here are a few more simple improvements:

  • Quote your branch names in case someone gets creative with Unicode. I don't think you need to quote $# and $? since they are integers, but I did so below just to be sure.

  • Name your arguments to make the rest of the script easier to read and maintain.

  • I'm guessing 90% of the time you'll be merging into master, and I prefer to order arguments as "from, to". For these reasons, I would reverse the arguments and provide a default for the "to" branch.

  • Telling the user they need to pass two arguments isn't as useful as telling them what those two arguments represent. Provide a nice usage message like other well-behaved scripts.

Put it Together

#!/bin/bash -x
set -e

function die () {
    echo "$1"
    exit 1

[[ "$#" -eq 1 || "$#" -eq 2 ]] || die "Usage: git-m <from-branch> [<to-branch>]"


git show-ref --verify --quiet refs/heads/$from || die "Branch $from does not exist"
git show-ref --verify --quiet refs/heads/$to || die "Branch $to does not exist"

git checkout $to;
git merge --ff-only $from;
git branch -d $from;
  • 1
    \$\begingroup\$ I prefer the order I've got as it's the same order I use when I typically rebase: git rebase master feature. To flip this would confuse me even if that rebase command is still "from, to". Plus, when doing this manually, you checkout the first branch and merge the second. That's an easy way to remember the order. I agree with everything else you're saying. \$\endgroup\$ Jun 29, 2014 at 2:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.