Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm trying to create a git alias that merges the currently checked out branch into the master branch. Specifically I'd want to quickly get my master branch get up to speed with what I'm working on. I've got the following:

[alias]
    co = checkout
    ff = !git co master && git merge work && git co work

However I'd like the alias to know which branch it was on and get back to it. I tried adding $1 but unfortunately I get a error on the last checkout in the alias:

# with
[alias]
    co = checkout
    ff = !git co master && git merge $1 && git co $1

> git ff work
Switched to branch 'master'
Already up-to-date.
error: pathspec 'work' did not match any file(s) known to git.

Anyone knows why it does this? (I'm on a Mac by the way)

share|improve this question
    
Related topic on stackoverflow though it doesn't answer the issue that I have. –  Spoike Jun 12 '12 at 12:15

2 Answers 2

up vote 5 down vote accepted

If you're going to use positional parameters in git aliases, be sure to specify sh -c. The following worked for me locally:

ff = !sh -c 'git checkout master && git merge "$1" && git checkout "$1"' -

The "why" relates to the way git parses the alias commands and is summed up in this gmane thread.

The - at the end of the command signals sh that option processing is finished. From man sh:

A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments. An argument of - is equivalent to --.

If it weren't present, it would introduce a bug in the alias, by treating $1 as an option on the sh command instead of as a positional argument. Consider this trivial example:

$ sh -c 'echo $1' foo          # equivalent to 'echo' without argument

$ sh -c 'echo $1' - foo        # will pass 'foo' to the string as $1
foo

In the first case, 'foo' was consumed by sh as an option. In the second, it's correctly interpreted as $1 on the string.

share|improve this answer
    
Works like a charm, thanks! –  Spoike Jun 13 '12 at 14:06
    
P.S. Why the dash at the end? –  Hari Karam Singh Sep 11 '13 at 16:58
    
@HariKaramSingh: Edited the answer with more information. –  Christopher Sep 11 '13 at 18:29

Here's a version with which you don't need to specify the current branch and can choose any target branch:

merge-into = !sh -c '_CURRENT_BRANCH=$(git symbolic-ref --short HEAD) && git checkout $1 && git merge $_CURRENT_BRANCH && git checkout $_CURRENT_BRANCH' -

Usage (from my-branch):

git merge-into master
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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