Git Alias - Multiple Commands and Parameters

84,503

Solution 1

This will work (tested with zsh and bash):

[alias] chs = !git checkout $1 && git status

Solution 2

This targets Windows batch / msysgit bash; might not work on other environments.

As Olivier Verdier and Lily Ballard have said

[alias] chs = !git checkout $1 && git status

almost works, but gives a spurious extra insertion of the argument ...

git chs demo -> git checkout demo && git status demo

But if you add && : to the end of your alias, then the spurious argument is consumed into a location tag.

So

[alias] chs = !git checkout $1 && git status && :

gives the correct output ... git chs demo -> git checkout demo && git status

Solution 3

You can define a shell function.

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"

Solution 4

I was able to create multi-line and quite complex git aliases. They work fine on Windows but I assume they'd work elsewhere too, for example:

safereset = "!f() { \
                trap 'echo ERROR: Operation failed; return' ERR; \
                echo Making sure there are no changes...; \
                last_status=$(git status --porcelain);\
                if [[ $last_status != \"\" ]]; then\
                    echo There are dirty files:;\
                    echo \"$last_status\";\
                    echo;\
                    echo -n \"Enter Y if you would like to DISCARD these changes or W to commit them as WIP: \";\
                    read dirty_operation;\
                    if [ \"$dirty_operation\" == \"Y\" ]; then \
                        echo Resetting...;\
                        git reset --hard;\
                    elif [ \"$dirty_operation\" == \"W\" ]; then\
                        echo Comitting WIP...;\
                        git commit -a --message='WIP' > /dev/null && echo WIP Comitted;\
                    else\
                        echo Operation cancelled;\
                        exit 1;\
                    fi;\
                fi;\
            }; \
            f"

I wrote a post and have a few more examples here.

Solution 5

[alias]
chs = !git branch && git status
Share:
84,503

Related videos on Youtube

Stella
Author by

Stella

Updated on March 21, 2021

Comments

  • Stella
    Stella about 3 years

    I am trying to create an alias that uses both multiple Git commands and positional parameters. There are Stackoverflow pages for each, and it would appear painfully obvious to do both, but I am having trouble.

    As an example, I want to switch to branch foo and perform a status. So in my .gitconfig, I have:

      [alias] 
         chs = !sh -c 'git checkout $0 && git status'
    

    which doesn't work. Whereas something like this will work.

    chs = !sh -c 'git checkout $0'
    
    echoes = !sh -c 'echo hi && echo bye'
    

    Any insight would be appreciated.

    • Marcus Becker
      Marcus Becker over 7 years
      My alias: git config --global alias.go '!git commit -a && git pull --rebase && git push && git status'. Note: Use simple quotes.
  • Lily Ballard
    Lily Ballard over 12 years
    No it won't. Git will transform git chs foo into git checkout && git status foo
  • Stella
    Stella over 12 years
    When I try that, I get pathspec error ('$1' did not match any file(s) known to git)
  • Stella
    Stella over 12 years
    I saw this on another stackoverflow page, but my cygwin terminal says that the function is not recognized when I try to run it.
  • Olivier Verdier
    Olivier Verdier over 12 years
    I tested it, it works perfectly... perhaps it depends on your shell? (I use zsh)
  • Lily Ballard
    Lily Ballard over 12 years
    @Stella: I left a closing quote in there that's not useful this config file syntax. Make sure you didn't have it.
  • Lily Ballard
    Lily Ballard over 12 years
    Interesting, git actually does fill in the positional variables now in shell aliases. But it's still broken, because it also tacks them on as arguments. An alias of echo $1 && echo done, when invoked with the argument 'foo', will output both "foo" and "done foo".
  • Stella
    Stella over 12 years
    Wow... Unfortunately, this was all a version problem. I was using Git 1.7.3, and neither of these methods worked. I updated to 1.7.6 and voila, everything worked. Thanks guys!
  • Stella
    Stella over 12 years
    Wow... Unfortunately, this was all a version problem. I was using Git 1.7.3, and neither of these methods worked. I updated to 1.7.6 and voila, everything worked. Thanks guys!
  • Lily Ballard
    Lily Ballard over 12 years
    @Stella: That sounds very strange. AFAIK the git alias stuff hasn't changed in quite a long time. I can't think of any reason whatsoever why upgrading from 1.7.3 to 1.7.6 would cause a simple shell alias to start working. But I guess I shouldn't question something that worked ;)
  • bitops
    bitops about 12 years
    Works for me also, git version 1.7.4.4
  • Elijah Lynn
    Elijah Lynn almost 11 years
    What is the preceding exclamation point for on the first invocation of git?
  • drzaus
    drzaus about 10 years
    if using Windows I think you have to surround the shell function definition with double-quotes "
  • Lily Ballard
    Lily Ballard about 10 years
    @ElijahLynn: In a git alias, a leading ! means pass the whole thing to the shell. Otherwise, it assumes you're trying to run another git command and passes it as arguments to the git binary.
  • yurisich
    yurisich almost 10 years
    Thanks! I actually had no problem using "!git fetch --prune --all; git pull --rebase upstream master; git push origin master" for my alias.
  • Brondahl
    Brondahl over 9 years
    Comment also added as an answer, please shout if I should remove one post or the other. In a windows environmend (cmd line, or msysgit bash) you can append && : to your alias, and that will consume the additional insertion of the parameter (turns it into a location tag, which isn't printed.) Don't know whether this, or some equivalent will work in other environments.
  • Ohad Schneider
    Ohad Schneider over 9 years
    Olivier's answer didn't work for me using parameters (OSX). This worked perfectly.
  • Clay
    Clay about 9 years
    The && : is gold and makes this solution work for commands where the extra argument would be problematic.
  • a user
    a user about 9 years
    one imrovement to this would be to add !f() { : reset to get completions from reset command github.com/git/git/blob/master/contrib/completion/…
  • Lily Ballard
    Lily Ballard about 9 years
    Huh, I wonder why it differs. I'll go ahead and update my answer to include the quotes. And it looks like git config does quote the value by default when it writes it in the first place.
  • Lily Ballard
    Lily Ballard about 9 years
    @Brondahl Clever. I'd recommend ;: instead of && : though. And that works just fine on unix as well.
  • Nick Volynkin
    Nick Volynkin almost 9 years
    Great job! What licence is that article published under? Would you mind if I translate parts of it for StackOverflow in Russian?
  • VitalyB
    VitalyB over 8 years
    @NickVolynkin Sorry about late reply. Thank you and of course, go ahead :)
  • Justin Morgan
    Justin Morgan almost 8 years
    @Clay (or anyone else) - Could someone explain to the BASH-challenged what && : does?
  • ElpieKay
    ElpieKay almost 8 years
    @JustinMorgan && means if the previous command turns 0 (success), then run the command after &&. ':', the colon, is a shell builtin command, which does nothing beyond expanding arguments and performing redirections and return the status 0. Here're some usages: 1. a=123;$a errors, but a=123; : $a does not. 2. : > hello.txt empties hello.txt. 3. if [ "$a" = "hello" ];then : ;fi runs okay but errors without ':'. It's like pass in python. 4. : this is a comment, the colon followed by space works as # in a comment line.
  • kchoi
    kchoi over 7 years
    this is such a hack... git should accept multiple command mode
  • Brondahl
    Brondahl about 7 years
    @kchoi So true :) And yet it appears to be a well-valued hack by the community :D
  • AutonomousApps
    AutonomousApps about 6 years
    What is the ! for?
  • Bernardo Dal Corno
    Bernardo Dal Corno over 4 years
    if you use quotes, ending an alias with a comment is better: [alias] chs = !"git checkout $1 && git status #" - it will turn extra arguments into comments that won't do a thing
  • Tyler Collier
    Tyler Collier about 4 years
    Thanks @ElpieKay for the explanation. My local git alias for one proejct was co = !git checkout public/compiled && git checkout $1 and when I'd do git co master I'd get the message error: pathspec 'master' did not match any file(s) known to git.. I didn't think this answer would be useful for me because the first thing it mentions is Windows and I'm on Linux. But you explained why.
  • laurent
    laurent almost 4 years
    I couldn't find doc for the ! but as far as I can see git by default will assume that the alias is a git command so t = status will work. However if you try t = git status it won't work (will say "git" command not found). So that where the ! comes in, it tells it to run the command as if it was a shell, and normally you need this when you have multiple git commands per alias, so you can have t = !git status && git log for example and it will work.
  • Jacob Lockard
    Jacob Lockard almost 4 years
    Here's a StackOverflow question that deals with exclamation points (!) in Git aliases: stackoverflow.com/questions/21083933/….
  • imme
    imme over 3 years
    Your example will expand to: git echo this is my testing string this is my testing string Adding a # to the end will fix it (don't forget the double quotes around the command alias).
  • imme
    imme over 3 years
    in .gitconfig: a0 = "!echo $*" and a1 = "!echo $* #" . To test them: git a0 hallo daar ; git a1 hallo daar
  • Rohim Chou
    Rohim Chou over 3 years
    If the alias expansion is prefixed with an exclamation point, it will be treated as a shell command. git-scm.com/docs/git-config
  • Alexander Malakhov
    Alexander Malakhov about 3 years
    @NickVolynkin, did you translate it eventually?
  • Devin Rhode
    Devin Rhode about 3 years
    Does git v2.2x still have these issues?
  • Brondahl
    Brondahl about 3 years
    @DevinGRhode No idea. Why don't you test it and tell us?
  • Kramer
    Kramer about 2 years
    @imme What does the # at the end do? It worked for me but I'd like to understand it.
  • imme
    imme about 2 years
    See this "demo" stackoverflow.com/a/63890372/165330 (it seems that git adds the arguments after replacing the alias with the defined alias, using $* in the alias already puts the arguments in there, so the rest should be ignored, which happens with the # at the end, making the rest of the command a comment.