Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git配置别名转义_Git_Bash_Escaping_Git Alias - Fatal编程技术网

Git配置别名转义

Git配置别名转义,git,bash,escaping,git-alias,Git,Bash,Escaping,Git Alias,我试图编写一个git别名,从提交消息中删除字符串“[ci skip]”(放在消息的末尾),但转义有问题。别名从作为参数传递到头的提交中获取所有提交 如果我运行以下命令: 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 \\\"

我试图编写一个git别名,从提交消息中删除字符串“[ci skip]”(放在消息的末尾),但转义有问题。别名从作为参数传递到
头的提交中获取所有提交

如果我运行以下命令:

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\\\"\" $0..HEAD'

我运行了
git unwip master
它抱怨配置不好,但我希望它的行为与前面的命令一样。如何修复此问题?

编辑此解决方案并非在所有情况下都有效。是一种正确的解决方案,适用于所有情况

我使用
bash
作为命令行,以下别名对我很有用:

unwip = "!f() { git filter-branch --msg-filter 'sed -e "s/[ci skip/]$/g"' $1..HEAD ; }; f"

唯一的缺点是您正在指定解释器,并且总是使用
sh
。在我的例子中,我依赖于用户的shell。虽然我不认为这在任何主要的shell中都会是一个问题,因为我们只做基本的工作。

通用解决方案

让一个
git
别名正确地通过解析器可能是一组令人难以置信的
\\\\“
杂音,因此我创建了两个别名:

# 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
+,例如:

\”

转换为适合别名的带引号的字符串:

$ git quote-string
echo '\"'
“!echo'\\\'\\'\\\”

为了引用一个多行字符串,我写了一个较长的字符串,建议您按以下方式运行:

git引号字符串|

回答OP的具体问题

在OP的命令上使用
git quote string
,我得到:

“!git筛选器分支-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"
只需将
debug
插入
git
和通常会出现的内容之间,例如OP的问题:

git debug unwip


+
git
使用
/bin/sh
执行以
*开头的别名。要解决此问题,请创建一个命令行,如:
bash-c'echo\\\”
然后将其传递给
git quote string


*
请参见“调试”标题以获取证据

只是猜测:可能还可以通过额外的转义反斜杠来屏蔽从方括号中转义的反斜杠,例如
\\\[ci skip\\\\]
?@Dilettant无法正常工作。这是一个不正确的示例-
sed-e之后的
实际上结束了第一个带引号的字符串。彩色语法高亮显示演示了这一点。幸运的是,
字符位于第二个带引号的字符串中,否则
git
将处理
作为注释字符,忽略行的其余部分。请参阅以获得正确的解决方案。非常好!一个问题是当我运行
git quote string
时。你在帖子中也引用了
gitshellquote
,我猜你的意思是
quote-string
?谢谢。我修复了术语,并从我的工作
gitconfig
中复制/粘贴了
quote string
。我还为多行别名添加了一个脚本。如果您仍然存在多行输出问题,请在聊天室中交谈?您粘贴的新别名似乎与旧别名相同。但由于某种原因,我无法邀请你。
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"