Add a Git alias containing a semicolon

2019-03-27 00:13发布

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?

6条回答
我命由我不由天
2楼-- · 2019-03-27 00:54

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.

查看更多
男人必须洒脱
3楼-- · 2019-03-27 00:55

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\" ; '"
查看更多
虎瘦雄心在
4楼-- · 2019-03-27 01:08

I have

[alias]
  sm-clean-all = "submodule foreach --recursive 'git clean -fXd'"
查看更多
小情绪 Triste *
5楼-- · 2019-03-27 01:08

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'
查看更多
贼婆χ
6楼-- · 2019-03-27 01:11

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
查看更多
放荡不羁爱自由
7楼-- · 2019-03-27 01:19

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.

查看更多
登录 后发表回答