为什么引用参数在 git 别名中不起作用? [英] Why does quoting arguments not do anything in git aliases?

查看:56
本文介绍了为什么引用参数在 git 别名中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 ~/.gitconfig:

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

它的行为如下:

$ git print
a
b
c

但是现在我把它改成下面的~/.gitconfig:

But now I change it to the following ~/.gitconfig:

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

然而 ab 仍然进行分词:

and yet the a and b still undergo word splitting:

$ git print
a
b
c

如果 "" 引号不能防止分词,那么它们在做什么?
命令是如何解析的?

If the "" quotes aren't preventing word-splitting then what are they doing?
How are the commands parsed?

推荐答案

Git 的配置语言解析器 出于自身目的使用双引号:

Git's configuration-language parser uses double quotes for its own purposes:

... Doublequote " 和反斜杠可以通过将它们分别转义为 \"\\ 来包含在内.读取时删除其他字符前面的反斜杠;例如,\t 读作 t\0 读作 0 ...

... Doublequote " and backslash can be included by escaping them as \" and \\, respectively. Backslashes preceding other characters are dropped when reading; for example, \t is read as t and \0 is read as 0 ...

当这个特定的段落讨论小节名称时,双引号和双反斜杠规则也适用于小节名称之外.这些引号的其余部分适用于任何地方,除了小节名称中的 \t=t 类型:

While this particular paragraph is discussing subsection names, the double-quote and double-backslash rules apply outside subsection names as well. The rest of these quotes apply everywhere, except for the \t=t kind of thing in subsection names:

在双引号内,双引号 " 和反斜杠 \ 字符必须转义:使用 \" for ";\\ 用于 \.

Inside double quotes, double quote " and backslash \ characters must be escaped: use \" for " and \\ for \.

可以识别以下转义序列(在 \"\\ 旁边): \n 用于换行符 (NL),\t 用于水平制表(HT,TAB)和 \b 用于退格(BS).其他字符转义序列(包括八进制转义序列)无效.

The following escape sequences (beside \" and \\) are recognized: \n for newline character (NL), \t for horizontal tabulation (HT, TAB) and \b for backspace (BS). Other char escape sequences (including octal escape sequences) are invalid.

请注意,这些都与别名没有任何关系:这些规则适用于 .gitconfig 中的所有行>.git/config 文件.(这在例如子模块路径中很重要,尽管通常不会编码一个双引号.)

Note that none of this has anything to do with aliases specifically: these rules apply to all lines in a .gitconfig or .git/config file. (This matters in, e.g., submodule paths, though one wouldn't generally encode a double quote in one.)

现在,配置解析器完成读取.git/config文件后,如果该行在alias部分,它定义别名.在该别名中,双引号确实可以防止分词:

Now, after the configuration parser is done reading the .git/config file, if the line is in an alias section, it defines an alias. Within that alias, double quotes do prevent word-splitting:

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

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

请注意,首先要通过配置解析器,这些必须用反斜杠给出.为了避免这种特殊的烦恼,我们可以改用单引号:

Note that to get past the configuration parser in the first place, these had to be given with backslashes. To avoid that particular annoyance we can use single quotes instead:

[alias]
    foo = log 'a b'

产生相同的结果.

如果别名是 shell 别名(以 ! 为前缀),则整个字符串(当然不包括感叹号)将被馈送到 shell.要观察这一点,请使用 GIT_TRACE:

If the alias is a shell alias (prefixed with !), the entire string (minus the exclamation point of course) is fed to the shell. To observe that, use 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

如果我们在配置解析器后面得到双引号,它们的效果是一样的:

If we get double quotes past the configuration parser, they have the same effect:

$ 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 输出所示),然后 shell 本身将它们变成了一个反斜杠,其中 printfn 组合以形成换行符.

The reason we need four backslashes is, of course, that the Git configuration parser turned them into two backslashes (as shown in the GIT_TRACE=1 output) and the shell itself then turned them into one backslash, which printf combined with the n to make a newline.

尝试别名:

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

失败:

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

因为 Git 本身正在运行其逐行解析器并且对未关闭的引用不满意.

because Git itself is running its line-by-line parser and is unhappy with the unclosed quote.

这篇关于为什么引用参数在 git 别名中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆