3

I got an error two hours ago from this alias in the .gitconfig file, which is:

[alias]
   chist = log --graph -10 --pretty=format:"%C(cyan)%h%Creset  %<(20,trunc)%s  %Cgreen%<(11,trunc)%an%Creset  %as  %C(yellow)%G?%Creset  %<(5,trunc)%GT %Cred%d"

The error:

$ git chist
fatal: ambiguous argument '%<(20,trunc)%s': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

It seems that the pair of double quotation marks disappeared and $<(20,trunc)%s was treated as an argument to the git log subcommand.

However, If I replaced " with ', the alias would make a desired behavior.

So I have referred to the following documents in order to resolve my question:

According to the first link, the syntax is name = value and if value needed to have leading or trailing spaces, value should be quoted with ". However, in the case of chist, since its value starts with log --graph..., its value itself is not quoted with ", isn't it? So I think this rule can't be applied to my situation.

In the second link, it says "the usual shell quoting" is supported. So I made a following test:

test = abc"def"ghi
text = abc'def'ghi

Let's see how it is parsed:

$ git config --list | grep "alias"
alias.test=abcdefghi
alias.text=abc'def'ghi

I'm afraid this is a contradiction. It's because, if the usual shell quoting were supported, then the value of alias.text should be abcdefghi.

1
  • 3
    Did you directly edit your .gitconfig file? When using the appropriate commands to add/modify/remove aliases with git config <alias.name> '<effect>' you don't have to wonder about how things are quoted (apart from maybe some rare edge cases). Commented Aug 27 at 7:11

1 Answer 1

2

A short answer then a repeat with longer explanations.

Config file syntax supports comments, line splicing, value trimming and a limited number of escapes, and supports doublequoting to bypass comment and trim processing (you're mostly interested in only the last three paragraphs of that syntax section).

To get the doublequotes in your chirt alias definition past the config file lexer you have to escape them, with a backslash. As it stands your resulting alias item value doesn't have any doublequotes at all.

Singlequotes aren't config file syntax, they're just passed through.

It's only the resulting alias item values that support shell quoting and escapes. git config --list doesn't know anything about that,it's just showing you the values Git sees and the alias processing will interpret.


If that seems disorienting—and multiple layers of syntax processing can trip up even old hands in an unguarded moment—then as reminder or recap or orientation/intro as the case may be, config items acquired from config files are read and rendered by Git's config file scanner according to those rules, just as config items acquired from the command line are read and rendered by the shell according to shell syntax rules, then Git's options scanner according to Git option-value syntax rules.

It's only then that the resulting config item values are interpreted according to the rules for that particular config item.

The doublequoting in your chirt alias value is going through config file syntax processing before the alias processing ever sees it. The doublequotes there are config file syntax, and aren't part of the resulting value, they're discarded the same way the shell discard quotes it sees as shell syntax marks. You don't want those quotes interpreted as config file item syntax, you want them as alias syntax, so you should escape them there to get them past that initial processing.

Singlequotes aren't config file syntax markers at all.

It's only the resulting alias item values that support shell quoting and escapes; git config --list doesn't know anything about that,it's just showing you the values Git sees and the alias processing will interpret.


I see that the config file syntax docs paragraph that actually says doublequotes in values shut off comment recognition was, I'm guessing inadvertently, deleted in commit 5f456b3c26… in 2015. The config file syntax is so widely taken for granted that nobody noticed for ten years that Git's doc stopped mentioning that bit. Ouch.

Sign up to request clarification or add additional context in comments.

3 Comments

I found this passage highly lacking. While it mentions that double-quotes are needed to include leading and trailing spaces, it does not say what happens with dq in the middle of the value. The remark "shell quoting and escaping are supported" is misleading at best. There is no shell quoting going on, otherwise, single-quotes would have special meaning, too, but the don't. The values have their own quoting rules, which aren't too complicated, but they are not expressed anywhere in the documentation.
But the shell quoting and escaping are supported remark doesn't apply to general config item lexing at all, and nothing implies that it does. Shell quoting and escaping is interpreted in the alias values after they've been scanned in, with config-file-value quotes, escaping and comment processing already applied. It's late for me and I'm fading, I'll take a look at this again tomorrow.
I've learned many things from your kind explanation. I sincerely thank you for taking your golden time to help me. Also, it was helpful for me to look the commit you've mentioned: github.com/git/git/commit/5f456b3c26. Deleted Line 72~77.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.