5

I have created an alias for catching up my tracking branches as needed. Here's the current line from the [alias] section of my .gitconfig:

catchup = !CURRENTBRANCH=$(git symbolic-ref --short HEAD) && echo Currently on $CURRENTBRANCH - switching to $1 && git checkout $1 && git merge origin/$1 && echo Going back to $CURRENTBRANCH && git checkout "$CURRENTBRANCH"

I use it as follows (for example):

git catchup new_design

This code results in (for example):

Currently on integration
Switched to branch 'new_design'
Your branch is behind 'origin/new_design' by 1 commit, and can be fast-forwarded.
Updating c82f7db..51eea8a
Fast-forward
 themes/theme1/css/styles.less | 17 +++++++++++++++++
 themes/theme1/js/app.js       |  6 +++---
 2 files changed, 20 insertions(+), 3 deletions(-)
Going back to integration
error: pathspec 'new_design' did not match any file(s) known to git.

I have tried the last command in the alias both with and without the double-quotes, with the same result.

Anyone know how to resolve that error at the end?

For those who might suggest using git pull, it doesn't resolve my problem, and would require entering my password. This alias is to be used if I have recently used git fetch, and have no need to go back to the remote repo.

I am running git bash on Windows 7, fyi.

mwotton
  • 2,170
  • 18
  • 36
  • Even though it should already be the case, try: 1/ adding a `git fetch` as the first command, 2/ `git checkout -t $1 origin/$1` when firs t switching. – VonC Oct 08 '12 at 06:15
  • Are you saying this is the cause of the error? The idea is to only use this on pre-existing tracking branches. I tried it anyway - it gave `fatal: Missing branch name; try -b`, and then if I use `git checkout -t origin/$1` (which looks more correct) I get `fatal: a branch named 'new_design' already exists` – mwotton Oct 08 '12 at 06:22
  • 1
    Can you add a `git branch -a` before the last `git checkout`? (to check on which branch git think you are after the merge) – VonC Oct 08 '12 at 06:33
  • 2
    Could it be that git automatically appends the parameter (here `new_design` in `git catchup new_design`) to the end of the command string when executing it? This would mean that the last command is actually `git checkout integration new_design`, and this gives this error message. – Philipp Wendler Oct 08 '12 at 09:09
  • @VonC: git symbolic-ref --short HEAD would be a more concise output, but yes, I have tried this and confirmed that I am on the expected branch at that point. – mwotton Oct 09 '12 at 00:15
  • @Phillipp Wendler: that sounds like it might be a possibility. How would I check this? – mwotton Oct 09 '12 at 00:16
  • @PhilippWendler that is exactly what was happening - as seen here: http://stackoverflow.com/questions/7534184/git-alias-multiple-commands-and-parameters#comment9128399_7534289 – mwotton Oct 09 '12 at 05:14

2 Answers2

3

Use a shell function for the alias:

[alias]

catchup = "!f() { CURRENTBRANCH=$(git symbolic-ref --short HEAD) && .... ;}; f"

There the handling of $n works as expected.


The OP mwotton confirms in the comments that the following works:

catchup = "!_(){ CURRENTBRANCH=$(git symbolic-ref --short HEAD) ; echo \"Currently on \"$CURRENTBRANCH\" - switching to \"$@ ; git checkout $@ ; git merge origin/$@ ; echo \"Going back to \"$CURRENTBRANCH ; git checkout $CURRENTBRANCH; }; _"

In multi-line, for more visibility:

catchup = "!_(){ 
  CURRENTBRANCH=$(git symbolic-ref --short HEAD) ; 
  echo \"Currently on \"$CURRENTBRANCH\" - switching to \"$@ ; 
  git checkout $@ ; 
  git merge origin/$@ ; 
  echo \"Going back to \"$CURRENTBRANCH ; 
  git checkout $CURRENTBRANCH; }; _"
Community
  • 1
  • 1
Stefan Näwe
  • 3,040
  • 1
  • 18
  • 19
  • This is going to require more skills in shell scripting for bash than I currently have. A quick try gives: `f: -c: line 0: syntax error near unexpected token \`{CURRENTBRANCH=$(git symbolic-ref --short HEAD)' f: -c: line 0: \`f(){CURRENT BRANCH=$(git symbolic-ref --short HEAD) ; echo Currently on $CURRENTBRANCH - switching to $1 ; git checkout $1 ; git merge origin/$1 ; echo Going back to $CURRENTBRANCH ; git checkout $CURRENTBRANCH)}; f "$@"'` – mwotton Oct 09 '12 at 00:29
  • Nevermind, I got my skills up to scratch. I ended up with this: `catchup = "!_(){ CURRENTBRANCH=$(git symbolic-ref --short HEAD) ; echo \"Currently on \"$CURRENTBRANCH\" - switching to \"$@ ; git checkout $@ ; git merge origin/$@ ; echo \"Going back to \"$CURRENTBRANCH ; git checkout $CURRENTBRANCH; }; _"` – mwotton Oct 09 '12 at 00:53
  • @mwotton good feedback, and +1 to Stefan. I took the liberty to include your conclusion in Stefan's answer for more visibility. – VonC Oct 09 '12 at 05:35
  • Where can I get some documentation on things like '$@' and '@-1' - no idea what those are? – Mark Gibaud Mar 20 '13 at 13:50
  • @MarkGibaud I used http://tldp.org/LDP/abs/html/ to learn bash scripting. Before I embarked upon this endeavour, I had no real bash scripting experience. This guide got me through, but you will need to be patient. – mwotton Apr 22 '13 at 16:06
1

Late for the party.. The reason it failed is that git runs the command as

git catchup new_design
# turns
CURRENTBRANCH= ... && git checkout "$CURRENTBRANCH\" new_design

That is, it appends "new_design" to the command. A proof of this is simple to demonstrate:

# [alias]
#   proof = !echo fixed text

> git proof tryme
# prints "fixed text tryme", not "fixed text"

So, an alternate option to stefan's answer is to use the comment trick

# [alias]
#   proof = "!echo fixed text #"

> git proof tryme
# prints "fixed text", since command it ranned was
# echo fixed text #tryme

catchup = "!CURRENTBRANCH=$(git symbolic-ref --short HEAD) && echo Currently on $CURRENTBRANCH - switching to $1 && git checkout $1 && git merge origin/$1 && echo Going back to $CURRENTBRANCH && git checkout \"$CURRENTBRANCH\" #"

# multiline version:
catchup = "! \
  CURRENTBRANCH=$(git symbolic-ref --short HEAD) && \
  echo Currently on $CURRENTBRANCH - switching to $1 && \
  git checkout $1 && \
  git merge origin/$1 && \
  echo Going back to $CURRENTBRANCH && \
  git checkout \"$CURRENTBRANCH\" \
#"

Notes:

  • "!..." and !"..." are equivalent
  • watch out for "\ " endings (with spaces after), it won't work!
  • this trick works even with use of "all parameters" ($*), since it prevents at all the append
Bernardo Dal Corno
  • 1,858
  • 1
  • 22
  • 27