Git 配置别名转义
Git config alias escaping
我正在尝试编写一个 git 别名,从提交消息中删除字符串“[ci skip]”(位于消息末尾),但我逃跑有问题。别名获取作为参数传递给 HEAD
.
的所有提交
如果我运行以下命令:
git filter-branch -f --msg-filter "sed -e \"s/\[ci skip\]$//g\"" master..HEAD
它按预期工作。无论如何,如果我创建以下别名:
unwip = !sh -c 'git filter-branch -f --msg-filter \"sed -e \\"s/\[ci skip\]$//g\\"\" [=12=]..HEAD'
和我 运行 git unwip master
它抱怨配置错误,但我希望它的行为与以前的逗号一样。我该如何解决这个问题?
编辑此解决方案并非在所有情况下都有效。 是适用于所有情况的正确解决方案。
我正在使用 bash
作为命令行,以下别名对我有用:
unwip = "!f() { git filter-branch --msg-filter 'sed -e "s/[ci skip/]$/g"' ..HEAD ; }; f"
唯一的缺点是您要指定解释器并始终使用 sh
。在我的例子中,我依赖于用户的 shell。虽然我认为这不会成为任何主要 shell 的问题,因为我们只做基本的事情。
通用解决方案
获取git
别名以正确传递解析器可能是mind-boggling组\\"
噪音,所以我创建了两个别名:
# Quote / unquote a sh command, converting it to / from a git alias string
quote-string = "!read -r l; printf \\"!; printf %s \"$l\" | sed 's/\([\\"]\)/\\\1/g'; printf \" #\\"\n\" #"
quote-string-undo = "!read -r l; printf %s \"$l\" | sed 's/\\\([\\"]\)/\1/g'; printf \"\n\" #"
这允许您将您可以输入的任何内容转换为 sh
+,例如:
$ echo '\"'
\"
转换为适合别名的带引号的字符串:
$ git quote-string
echo '\"'
"!echo '\\"' #"
为了引用一个 multi-line 字符串,我写了一个更长的 script,我建议你 运行 为:
git quote-string |
sponge
回答 OP 的具体问题
在 OP 的命令中使用 git quote-string
,我得到:
"!git filter-branch -f --msg-filter \"sed -e \\"s/\[ci skip\]$//g\\"\" master..HEAD #"
因此,要使用 OP 的首选别名,请在 ~/.gitconfig
中的 [alias]
下添加:
unwip = "!git filter-branch -f --msg-filter \"sed -e \\"s/\[ci skip\]$//g\\"\" master..HEAD #"
调试
有时很高兴看到引擎盖下发生了什么。试试这个别名:
debug = "!set -x; GIT_TRACE=2 GIT_CURL_VERBOSE=2 GIT_TRACE_PERFORMANCE=2 GIT_TRACE_PACK_ACCESS=2 GIT_TRACE_PACKET=2 GIT_TRACE_PACKFILE=2 GIT_TRACE_SETUP=2 GIT_TRACE_SHALLOW=2 git"
只需在 git
和通常后面的内容之间插入 debug
,例如对于 OP 的问题:
git debug unwip
+
git
使用 /bin/sh
执行以 !
* 开头的别名。要解决此问题,请创建如下命令行:bash -c 'echo \\"'
然后将其传递给 git quote-string
.
*
请参阅 "Debugging" 标题以获取证明
我正在尝试编写一个 git 别名,从提交消息中删除字符串“[ci skip]”(位于消息末尾),但我逃跑有问题。别名获取作为参数传递给 HEAD
.
如果我运行以下命令:
git filter-branch -f --msg-filter "sed -e \"s/\[ci skip\]$//g\"" master..HEAD
它按预期工作。无论如何,如果我创建以下别名:
unwip = !sh -c 'git filter-branch -f --msg-filter \"sed -e \\"s/\[ci skip\]$//g\\"\" [=12=]..HEAD'
和我 运行 git unwip master
它抱怨配置错误,但我希望它的行为与以前的逗号一样。我该如何解决这个问题?
编辑此解决方案并非在所有情况下都有效。
我正在使用 bash
作为命令行,以下别名对我有用:
unwip = "!f() { git filter-branch --msg-filter 'sed -e "s/[ci skip/]$/g"' ..HEAD ; }; f"
唯一的缺点是您要指定解释器并始终使用 sh
。在我的例子中,我依赖于用户的 shell。虽然我认为这不会成为任何主要 shell 的问题,因为我们只做基本的事情。
通用解决方案
获取git
别名以正确传递解析器可能是mind-boggling组\\"
噪音,所以我创建了两个别名:
# Quote / unquote a sh command, converting it to / from a git alias string
quote-string = "!read -r l; printf \\"!; printf %s \"$l\" | sed 's/\([\\"]\)/\\\1/g'; printf \" #\\"\n\" #"
quote-string-undo = "!read -r l; printf %s \"$l\" | sed 's/\\\([\\"]\)/\1/g'; printf \"\n\" #"
这允许您将您可以输入的任何内容转换为 sh
+,例如:
$ echo '\"'
\"
转换为适合别名的带引号的字符串:
$ git quote-string
echo '\"'
"!echo '\\"' #"
为了引用一个 multi-line 字符串,我写了一个更长的 script,我建议你 运行 为:
git quote-string |
sponge
回答 OP 的具体问题
在 OP 的命令中使用 git quote-string
,我得到:
"!git filter-branch -f --msg-filter \"sed -e \\"s/\[ci skip\]$//g\\"\" master..HEAD #"
因此,要使用 OP 的首选别名,请在 ~/.gitconfig
中的 [alias]
下添加:
unwip = "!git filter-branch -f --msg-filter \"sed -e \\"s/\[ci skip\]$//g\\"\" master..HEAD #"
调试
有时很高兴看到引擎盖下发生了什么。试试这个别名:
debug = "!set -x; GIT_TRACE=2 GIT_CURL_VERBOSE=2 GIT_TRACE_PERFORMANCE=2 GIT_TRACE_PACK_ACCESS=2 GIT_TRACE_PACKET=2 GIT_TRACE_PACKFILE=2 GIT_TRACE_SETUP=2 GIT_TRACE_SHALLOW=2 git"
只需在 git
和通常后面的内容之间插入 debug
,例如对于 OP 的问题:
git debug unwip
+
git
使用 /bin/sh
执行以 !
* 开头的别名。要解决此问题,请创建如下命令行:bash -c 'echo \\"'
然后将其传递给 git quote-string
.
*
请参阅 "Debugging" 标题以获取证明