如何解决PowerShell 中的 Git 配置双引号
这被问到 here,但没有为 PowerShell 提供解决方案。给出的解决方案不适用于 PowerShell(特别是 VSCode 中的 PowerShell 5.1)。
我试过了
git config --global mergetool.vscode.cmd '"code --wait $MERGED"'
但我丢失了双引号(即相应的 .gitconfig
文件中没有双引号)。仅供参考,单引号是将 $MERGED
作为字符串文字传递而不是让 PowerShell 尝试扩展它所必需的。
我也试过
echo '"code --wait $MERGED"' | git config --global mergetool.vscode.cmd
git config --global mergetool.vscode.cmd '`"code --wait $MERGED`"'
git config --global mergetool.vscode.cmd @'
code --wait $MERGED
'@
但没有任何效果。有没有办法在 PowerShell 中执行此操作?
另外,我研究了this question,以及
的解决方案git config --global mergetool.vscode.cmd '\"code --wait $MERGED\"'
也没有
git config --global mergetool.vscode.cmd "\"code --wait $MERGED\""
也不起作用。
我得到的最接近的是使用
git config --global mergetool.vscode.cmd '" code --wait $MERGED "'
但这会输出字符串中的空格:
[mergetool "vscode"]
cmd = " code --wait $MERGED "
解决方法
不幸的是,需要一个模糊的解决方法(有关通过可安装模块的通用解决方案,请参阅底部部分):
git config --global mergetool.vscode.cmd --% "\"code --wait $MERGED\""
注意:这假设您希望在 ~/.gitconfig
中得到以下内容,这可能不是您的意图:
[mergetool "vscode"]
cmd = \"code --wait $MERGED\"
相反,正如 one of the answers you link to 建议的那样,只有 $MERGED
部分应该被双引号加上嵌入双引号,在这种情况下,您应该使用(见底部的替代方案):
git config --global mergetool.vscode.cmd --% "code --wait \"$MERGED\""
那会给你:
[mergetool "vscode"]
cmd = code --wait \"$MERGED\"
也就是说,只有 shell 命令中那些单独的参数需要你的值构成,为了 shell > 必须用 "..."
括起来。
请注意,重新转义逐字 git
字符的是 "
。在给定的配置值中作为配置文件中的 \"
。配置文件中的 Unescaped "
- 具有 语法 函数 对于 git
本身 - 仅在您通过带有前导和/或尾随空格的值,以便将值作为一个整体进行分隔; 带有(内部)空格的值本身不需要手动双引号:git
将它们按原样存储在配置文件中,除了将嵌入的 \
转义为\\
和 "
为 \"
。
从 PowerShell 传递 --% "code --wait \"$MERGED\""
表示将 逐字 值 code --wait "$MERGED"
传递给 git config --global mergetool.vscode.cmd
的意图,这是 {{1 }} 命令行[1](sh
是一个兼容 POSIX 的 shell,sh
甚至在 Windows 上也可以使用,通过 git
实现随附),其中(环境)变量引用 bash
周围的 "..."
确保扩展值按原样传递给目标二进制文件 $MERGED
,即使它包含空格,例如。
您可以通过查询之后的值来验证这一点:
code
# After running the command above:
PS> git config --global mergetool.vscode.cmd
code --wait "$MERGED"
和配置文件格式记录在 here 中,也可以通过运行 git config
在本地获得,或者仅在类 Unix 平台上使用 git help config
解决方法的说明:
使用 man git-config
,即 stop-parsing symbol,允许您控制传递给外部程序的后续参数的精确引用(同时还抑制 PowerShell 变量的扩展,因此 --%
是保持原样),而 PowerShell 默认在执行自己的解析后在幕后执行重新引用。
撇开双引号整个命令行最终不是正确的方法,纯粹从 PowerShell 语法的角度来看,您尝试了什么,$MERGED
,应该 工作 - PowerShell 应该在幕后自动将其转换为 '"code --wait $MERGED"'
- 但从 PowerShell 7.1 开始,由于长期存在的错误,描述详情见this answer。
虽然显式 "\"code --wait $MERGED\""
转义嵌入的 \
字符。(!)通常是一种更好的解决方法,并且在 PowerShell (Core) 7+ 中可靠地工作,在 Windows PowerShell 中存在一些边缘情况,而您遇到了其中一种情况:
"
这在 Windows PowerShell 中不起作用的原因是它错误地得出 # Alternative workaround for *PowerShell (Core) v7+ only*
git config --global mergetool.vscode.cmd '\"code --wait $MERGED\"'
构成句法双引号的结论,因此没有将参数括在 {{1} };也就是说,它不传递 \"...\"
,而是只传递 "..."
作为目标进程命令行的一部分。
请注意,引用参数单独避免了讨论的边缘情况,因此即使在 Windows PowerShell 中,显式的 "\"...\""
转义也可以工作:
\"...\"
通过模块 \
的通用解决方案:
如果您想解决大多数[2](在Windows上)/所有(在Unix上)对外部程序调用的引用问题,考虑一下我的 Native
module 的 # Also works in Windows PowerShell,because the edge case is avoided.
git config --global mergetool.vscode.cmd 'code --wait \"$MERGED\"'
函数,它封装了所有必需的解决方法:
Native
[1] ie
似乎在调用 # Install the module in the current user's scope.
Install-Module Native
# Simply prepend `ie` to your external-program calls,which correctly
# handles all behind-the-scenes re-quoting,allowing you to focus on
# PowerShell syntax only.
ie git config --global mergetool.vscode.cmd 'code --wait "$MERGED"'
如下(使用带有占位符的 git
语法进行说明):sh
也就是说,在调用配置值中存储的命令行时,附加了 sh
提供的传递参数。请注意,第一个 post sh -c '<config-value> "$@"' '<config-value>' <git-supplied args>
参数再次是配置值,它绑定到 git
,即设置调用名称,因此不是传递数组的一部分- 通过参数,-c
。 $0
提供的传递参数的一个示例是要编辑的文件的路径,该文件被传递到存储在 "$@"
配置值中的命令行。
[2] 适用于所有外部程序的解决方案在 Windows 上从根本上是不可能的,因为每个程序都可以自行决定如何解析对传递的参数进行编码的字符串。但是,git
知道并适当地应用了一些普遍存在的模式,这特别使它与批处理文件和类似 core.editor
的可执行文件一起工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。