15

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?

Mechanical snail
  • 29,755
  • 14
  • 88
  • 113

6 Answers6

17

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.

Mechanical snail
  • 29,755
  • 14
  • 88
  • 113
5

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\" ; '"
Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278
3

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.

Tim Siegel
  • 1,171
  • 8
  • 6
2

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'
kenorb
  • 155,785
  • 88
  • 678
  • 743
2

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
Amber
  • 507,862
  • 82
  • 626
  • 550
0

I have

[alias]
  sm-clean-all = "submodule foreach --recursive 'git clean -fXd'"
linquize
  • 19,828
  • 10
  • 59
  • 83