Add a Git alias containing a semicolon
-
13-11-2019 - |
سؤال
When I try to create an alias
[alias]
my-alias = submodule foreach 'git foo ; git bar'
Git (version 1.7.1) spews the error
user@host:/path/repo.git$ git my-alias
error: unclosed quote
fatal: Bad alias.my-alias string
It appears that .gitconfig
uses weird parsing rules, so that ;
is treated as starting a line comment, even inside of a quote.
How do I specify this alias?
المحلول
Wrap the entire alias command in double quotes:
my-alias = "submodule foreach 'git foo ; git bar'"
The double quotes cause the .gitconfig
parser to pass the semicolon. The single quotes are still needed to delimit the argument to submodule foreach
; without them, it gets parsed as
submodule foreach 'git foo'
git bar
so that git bar
only gets executed once, at the end.
نصائح أخرى
Not sure if this is related to the semicolon, but here goes - here is another test for git alias, using bash
:
[alias]
testbash = "!bash -c \"ix=1; echo a\\$ix\""
test:
$ git testbash
a1
Any other form of escape gives me either plain old "fatal: bad config file line", or “Unterminated quoted string” or “unexpected EOF” (see also shell - Calling bash from sh (dash) with commands read from args, and "Unterminated quoted string"/"unexpected EOF" - Unix & Linux Stack Exchange)
Also for multiline:
[alias]
testbashm1 = "!bash -c \"ix=1; echo a\\$ix; \
echo b\\$ix \""
testbashm2 = "!bash -c 'ix=1; echo a$ix; \
echo b$ix '"
... and add \n\
to the end of line, if you want to use inline bash
comments (#
):
[alias]
testbashm3 = "!bash -c 'ix=1; echo a$ix; \n\
#echo b$ix ; \n\
echo \"c$ix\" ; '"
You need to use doublequotes ("
) rather than singlequotes ('
).
[alias]
foo = "submodule foreach 'echo foo; echo bar'"
bar = submodule foreach 'echo foo; echo bar'
$ git foo
foo
bar
$ git bar
fatal: Bad alias.bar string: unclosed quote
I have
[alias]
sm-clean-all = "submodule foreach --recursive 'git clean -fXd'"
Just wrap the command into double-quotes, e.g.:
foo = !"echo foo; echo bar"
To include semicolon for find
, double-escape it, like:
pull-all = !"find . -name .git -type d -print -execdir git pull origin \\;"
Same with your command:
my-alias = "submodule foreach 'git foo; git bar'"
For troubleshooting, prefix your command with GIT_TRACE=1
to debug your alias, e.g.
$ GIT_TRACE=1 git my-alias
18:16:07.904421 git.c:282 trace: alias expansion: my-alias => 'submodule' 'foreach' 'git foo; git bar'
18:16:07.904437 git.c:557 trace: exec: 'git-submodule' 'foreach' 'git foo; git bar'
18:16:07.904443 run-command.c:347 trace: run_command: 'git-submodule' 'foreach' 'git foo; git bar'
For complete flexibility, define and call a function:
[alias]
conf = ! " \
f () { \
git config \"$@\" --get-regexp . \
| sort; \
}; \
f"
This alias can be called as git conf
, git conf --local
or git conf --global
, and the extra options are inserted in the appropriate place.