Почему цитирование аргументов ничего не делает в псевдонимах git? - PullRequest
0 голосов
/ 07 мая 2019

У меня есть следующее ~/.gitconfig:

[alias]
    print = !printf %s\\\\n a b c

Оно ведет себя следующим образом:

$ git print
a
b
c

Но теперь я изменяю его на следующее ~/.gitconfig:

[alias]
    print = !printf %s\\\\n "a b" c

и все же a и b все еще подвергаются разделению слов:

$ git print
a
b
c

Если кавычки "" не препятствуют разделению слов, тогда что они делают?
Как анализируются команды?

1 Ответ

5 голосов
/ 07 мая 2019

Анализатор языка конфигурации Git использует двойные кавычки для своих собственных целей :

... Двойная кавычка " и обратная косая черта могут быть включены путем экранирования их как \"и \\ соответственно.Обратные слэши, предшествующие другим символам, удаляются при чтении;например, \t читается как t, а \0 читается как 0 ...

В то время как в этом конкретном абзаце обсуждаются названия подразделов, двойные кавычки и двойные кавычкиПравила обратной косой черты применяются и за пределами имен подразделов.Остальная часть этих кавычек применяется везде, кроме \t = t в именах подразделов:

Внутри двойных кавычек двойные кавычки " и обратная косая черта \ символов должныбыть экранированным: используйте \" для " и \\ для \.

Следующие escape-последовательности (кроме \" и \\) распознаются: \n для символа новой строки (NL), \t для горизонтальной табуляции (HT, TAB) и \b для возврата (BS).Другие escape-последовательности символов (включая восьмеричные escape-последовательности) являются недопустимыми.

Обратите внимание, что ничего из этого не имеет никакого отношения конкретно к псевдонимам: эти правила применяются к all строк в файле .gitconfig или .git/config.(Это имеет значение, например, в подмодульных путях, хотя обычно не кодируют двойные кавычки в одном.)

Теперь после анализатор конфигурации завершенЧтение файла .git/config, если строка находится в разделе alias, определяет псевдоним.В пределах этого псевдонима двойные кавычки предотвращают расщепление слов:

[alias]
    foo = log \"a b\"

$ git foo
fatal: ambiguous argument 'a b': unknown revision or path not in the working tree.

Обратите внимание, что для того, чтобы в первую очередь обойти анализатор конфигурации, их нужно было указывать с обратной косой чертой.Чтобы избежать этого конкретного раздражения, мы можем вместо этого использовать одинарные кавычки:

[alias]
    foo = log 'a b'

дает тот же результат.

Если псевдоним - псевдоним shell (с префиксом !) вся строка (за исключением, конечно, восклицательного знака) подается в оболочку.Чтобы наблюдать это, используйте GIT_TRACE:

[alias]
    foo = !printf %s\\\\n 'a b'

$ GIT_TRACE=1 git foo
23:15:46.947801 git.c:670               trace: exec: git-foo
23:15:46.948153 run-command.c:643       trace: run_command: git-foo
23:15:46.948883 run-command.c:643       trace: run_command: 'printf %s\\n '\''a b'\'''
a b

Если мы получим двойные кавычки после анализатора конфигурации, они будут иметь тот же эффект:

$ GIT_TRACE=1 git foo
23:16:24.919042 git.c:670               trace: exec: git-foo
23:16:24.919402 run-command.c:643       trace: run_command: git-foo
23:16:24.920114 run-command.c:643       trace: run_command: 'printf %s\\n "a b"'
a b

Причина, по которой нам нужно четыре обратных слешаРазумеется, что анализатор конфигурации Git превратил их в две обратные косые черты (как показано в выводе GIT_TRACE=1), а сама оболочка превратила их в одну обратную косую черту, которая printf в сочетании с n создала новую строку.

Попытка псевдонима:

    foo = !printf %s\\\\n "a b

завершается неудачно с:

fatal: bad config line 30 in file [path]/.gitconfig

, потому что сам Git запускает свой построчный синтаксический анализатор и недоволен незамеченной кавычкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...