Git Alias - Multiple Commands and Parameters
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
Related videos on Youtube
Stella
Updated on March 21, 2021Comments
-
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 over 7 yearsMy alias: git config --global alias.go '!git commit -a && git pull --rebase && git push && git status'. Note: Use simple quotes.
-
-
Lily Ballard over 12 yearsNo it won't. Git will transform
git chs foo
intogit checkout && git status foo
-
Stella over 12 yearsWhen I try that, I get pathspec error ('$1' did not match any file(s) known to git)
-
Stella over 12 yearsI 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 over 12 yearsI tested it, it works perfectly... perhaps it depends on your shell? (I use zsh)
-
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 over 12 yearsInteresting, 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 over 12 yearsWow... 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 over 12 yearsWow... 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 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 about 12 yearsWorks for me also, git version 1.7.4.4
-
Elijah Lynn almost 11 yearsWhat is the preceding exclamation point for on the first invocation of
git
? -
drzaus about 10 yearsif using Windows I think you have to surround the shell function definition with double-quotes
"
-
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 thegit
binary. -
yurisich almost 10 yearsThanks! I actually had no problem using
"!git fetch --prune --all; git pull --rebase upstream master; git push origin master"
for my alias. -
Brondahl over 9 yearsComment 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 over 9 yearsOlivier's answer didn't work for me using parameters (OSX). This worked perfectly.
-
Clay about 9 yearsThe
&& :
is gold and makes this solution work for commands where the extra argument would be problematic. -
a user about 9 yearsone 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 about 9 yearsHuh, 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 about 9 years@Brondahl Clever. I'd recommend
;:
instead of&& :
though. And that works just fine on unix as well. -
Nick Volynkin almost 9 yearsGreat job! What licence is that article published under? Would you mind if I translate parts of it for StackOverflow in Russian?
-
VitalyB over 8 years@NickVolynkin Sorry about late reply. Thank you and of course, go ahead :)
-
Justin Morgan almost 8 years@Clay (or anyone else) - Could someone explain to the BASH-challenged what
&& :
does? -
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, buta=123; : $a
does not. 2.: > hello.txt
empties hello.txt. 3.if [ "$a" = "hello" ];then : ;fi
runs okay but errors without ':'. It's likepass
in python. 4.: this is a comment
, the colon followed by space works as#
in a comment line. -
kchoi over 7 yearsthis is such a hack... git should accept multiple command mode
-
Brondahl about 7 years@kchoi So true :) And yet it appears to be a well-valued hack by the community :D
-
AutonomousApps about 6 yearsWhat is the
!
for? -
Bernardo Dal Corno over 4 yearsif 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 about 4 yearsThanks @ElpieKay for the explanation. My local git alias for one proejct was
co = !git checkout public/compiled && git checkout $1
and when I'd dogit co master
I'd get the messageerror: 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 almost 4 yearsI 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 sot = status
will work. However if you tryt = 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 havet = !git status && git log
for example and it will work. -
Jacob Lockard almost 4 yearsHere's a StackOverflow question that deals with exclamation points (!) in Git aliases: stackoverflow.com/questions/21083933/….
-
imme over 3 yearsYour 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 over 3 yearsin .gitconfig: a0 = "!echo $*" and a1 = "!echo $* #" . To test them: git a0 hallo daar ; git a1 hallo daar
-
Rohim Chou over 3 yearsIf 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 about 3 years@NickVolynkin, did you translate it eventually?
-
Devin Rhode about 3 yearsDoes git v2.2x still have these issues?
-
Brondahl about 3 years@DevinGRhode No idea. Why don't you test it and tell us?
-
Kramer about 2 years@imme What does the # at the end do? It worked for me but I'd like to understand it.
-
imme about 2 yearsSee 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.