Git过滤器和sed争夺`\ $`

时间:2018-04-04 13:37:21

标签: git sed quoting

我正在尝试使用git

编写sed过滤器
[filter "revisioner"]
        smudge = sed -e "s/\\\$Revision\\\$/\$Revision: $(GIT_EXEC_PATH=/usr/lib/git-core/ git describe --tag svn)\$/g"
        clean = sed -e "s/\\\$Revision: [^$]*\\\$/\$Revision\$/g"

要让sed做正确的事情,它希望有\的奇数来逃避$,但是git抱怨奇数\ 1}} with:

fatal: bad config line 2 in file .git/../.gitconfig

我真的不想将我的sed脚本移动到外部命令中,因为它是用户在使用我的存储库之前需要在他们的系统上设置的另一个移动部分。

有什么建议吗?

2 个答案:

答案 0 :(得分:5)

正确地进行转义解析通常是一个挑战,因为您必须考虑将解析命令的每个程序,并且您必须按顺序考虑它们。

torek的回答概述了适用于您案件的基本推理。我将添加以下内容,因为我认为最终结果更具可读性:

首先,让底层sed脚本在命令行中运行 - 在我的测试中,将$HI$转换为$Hello, World$ - 我使用了

sed -e 's/\$HI\$/$Hello World$/g'

单引号可防止bash弄乱转义,因此sed会看到\$并与文字$匹配。请注意,输出模式不需要此转义。

然后将它放在.git/config文件中,将每个反斜杠加倍,给出

clean = sed -e 's/\\$HI\\$/$Hello World$/g'

这适用于我的测试;如果它对您不起作用,我们可能需要更多信息来了解正在发生的事情。

答案 1 :(得分:3)

sed不需要奇数的反斜杠。 sed需要接收,无论是调用sed,还是两个字符的反斜杠,美元符号。

Git本身将两个反斜杠变为一个反斜杠。

Git调用以运行命令的shell也会将两个反斜杠转换为一个反斜杠,只要它在词汇上扫描未包含在单引号内的文本。

因此,如果您从四个反斜杠开始:

\\\\$

Git会将每对变成两个反斜杠:

\\$

然后shell会将这对反斜杠转换成一个反斜杠:

\$

之后sed会看到一个反斜杠后跟一个美元符号。

请注意,您必须在每个反斜杠被解释的点处加倍。如果再应用了一个级别的解释,则需要八个反斜杠。这种事情变得很难看,这就是为什么人们将这些转移到其他脚本中。如果您将脚本作为存储库中的已提交文件提供,则可能更容易处理...