Git 在 PowerShell 中配置双引号
Git Config Double Quotes in PowerShell
有人问过这个问题 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
逐字重新转义 "
个字符。在给定的配置值中作为配置文件中的 \"
。 未转义 "
在配置文件中 - 具有 语法 函数 for git
本身 - 仅在传递带有前导 and/or 尾随空格的值时使用,以便将值作为一个整体进行分隔; 带有(内部)空格的值不本身需要手动双引号:git
将它们按原样存储在配置文件中,除了转义嵌入式\
作为 \
和 "
作为 \"
.
从 PowerShell 传递 --% "code --wait \"$MERGED\""
表示将 逐字 值 code --wait "$MERGED"
传递给 git config --global mergetool.vscode.cmd
的意图,这是 git config --global mergetool.vscode.cmd
的正确表述=113=]sh
命令行[1](sh
是 POSIX 兼容的 shell git
通过随附的 bash
实现甚至在 Windows 上使用)其中 "..."
周围(环境)变量引用 $MERGED
确保扩展例如,值按原样传递给目标二进制文件 code
,即使它包含空格。
您可以通过查询之后的值来验证这一点:
# After running the command above:
PS> git config --global mergetool.vscode.cmd
code --wait "$MERGED"
git config
和配置文件格式记录 here,也可通过 运行 git help config
在本地获得,或者,仅在类 Unix 平台上,man git-config
解决方法说明:
--%
、stop-parsing symbol 的使用允许您控制传递给外部程序的后续参数的精确引用(同时还抑制 PowerShell 变量的扩展,因此 $MERGED
保持原样),而 PowerShell 默认情况下会在执行自己的解析后在幕后执行 重新引用 。
抛开对整个命令行的双引号最终不是正确的方法,纯粹从您尝试的 PowerShell 语法角度来看,'"code --wait $MERGED"'
, 应该 工作 - PowerShell 应该在幕后自动将其转换为 "\"code --wait $MERGED\""
- 但从 PowerShell 7.1 开始不会,由于一个长期存在的错误 ,在 this answer.
中有详细描述
虽然显式 \
-转义嵌入的 "
字符。(!) 通常 是一个更好的解决方法并且在 中可靠地工作PowerShell (Core) 7+,在 Windows PowerShell 中存在一些边缘情况,但您遇到了其中之一:
# Alternative workaround for *PowerShell (Core) v7+ only*
git config --global mergetool.vscode.cmd '\"code --wait $MERGED\"'
这在 Windows PowerShell 中不起作用的原因是它错误地认为 \"...\"
构成 syntactic 双引号,因此不会' t 将参数括在 "..."
中;也就是说,它不传递 "\"...\""
,而是仅传递 \"...\"
作为目标进程命令行的一部分。
请注意 单独 引用参数避免了讨论的边缘情况,因此显式 \
-转义甚至在 Windows PowerShell 中也有效:
# Also works in Windows PowerShell, because the edge case is avoided.
git config --global mergetool.vscode.cmd 'code --wait \"$MERGED\"'
通过模块的通用解决方案Native
:
如果你想解决 most[2] (on Windows) / all(在 Unix 上)调用外部程序,考虑我的 Native
module 的 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"'
[1] git
似乎正在调用 sh
如下(使用带占位符的 sh
语法进行说明):
sh -c '<config-value> "$@"' '<config-value>' <git-supplied args>
也就是说,调用存储在配置值中的命令行时附加 git
提供的传递参数。请注意,第一个 post -c
参数再次是配置值,它绑定到 [=64=]
,即设置调用名称,因此 不是 传递参数数组的一部分,"$@"
。 git
提供的传递参数的一个示例是要编辑的文件的路径,它被传递到存储在 core.editor
配置值中的命令行。
[2] 与 所有 外部程序一起工作的解决方案在 Windows 上基本上是不可能的,因为每个程序都可以自行决定它如何解析对传递的参数进行编码的字符串。但是,ie
了解并适当应用了一些广泛使用的模式,这使得它可以与批处理文件和类似 msiexec
的可执行文件一起稳健地工作。
有人问过这个问题 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
逐字重新转义 "
个字符。在给定的配置值中作为配置文件中的 \"
。 未转义 "
在配置文件中 - 具有 语法 函数 for git
本身 - 仅在传递带有前导 and/or 尾随空格的值时使用,以便将值作为一个整体进行分隔; 带有(内部)空格的值不本身需要手动双引号:git
将它们按原样存储在配置文件中,除了转义嵌入式\
作为 \
和 "
作为 \"
.
从 PowerShell 传递 --% "code --wait \"$MERGED\""
表示将 逐字 值 code --wait "$MERGED"
传递给 git config --global mergetool.vscode.cmd
的意图,这是 git config --global mergetool.vscode.cmd
的正确表述=113=]sh
命令行[1](sh
是 POSIX 兼容的 shell git
通过随附的 bash
实现甚至在 Windows 上使用)其中 "..."
周围(环境)变量引用 $MERGED
确保扩展例如,值按原样传递给目标二进制文件 code
,即使它包含空格。
您可以通过查询之后的值来验证这一点:
# After running the command above:
PS> git config --global mergetool.vscode.cmd
code --wait "$MERGED"
git config
和配置文件格式记录 here,也可通过 运行 git help config
在本地获得,或者,仅在类 Unix 平台上,man git-config
解决方法说明:
--%
、stop-parsing symbol 的使用允许您控制传递给外部程序的后续参数的精确引用(同时还抑制 PowerShell 变量的扩展,因此 $MERGED
保持原样),而 PowerShell 默认情况下会在执行自己的解析后在幕后执行 重新引用 。
抛开对整个命令行的双引号最终不是正确的方法,纯粹从您尝试的 PowerShell 语法角度来看,'"code --wait $MERGED"'
, 应该 工作 - PowerShell 应该在幕后自动将其转换为 "\"code --wait $MERGED\""
- 但从 PowerShell 7.1 开始不会,由于一个长期存在的错误 ,在 this answer.
虽然显式 \
-转义嵌入的 "
字符。(!) 通常 是一个更好的解决方法并且在 中可靠地工作PowerShell (Core) 7+,在 Windows PowerShell 中存在一些边缘情况,但您遇到了其中之一:
# Alternative workaround for *PowerShell (Core) v7+ only*
git config --global mergetool.vscode.cmd '\"code --wait $MERGED\"'
这在 Windows PowerShell 中不起作用的原因是它错误地认为 \"...\"
构成 syntactic 双引号,因此不会' t 将参数括在 "..."
中;也就是说,它不传递 "\"...\""
,而是仅传递 \"...\"
作为目标进程命令行的一部分。
请注意 单独 引用参数避免了讨论的边缘情况,因此显式 \
-转义甚至在 Windows PowerShell 中也有效:
# Also works in Windows PowerShell, because the edge case is avoided.
git config --global mergetool.vscode.cmd 'code --wait \"$MERGED\"'
通过模块的通用解决方案Native
:
如果你想解决 most[2] (on Windows) / all(在 Unix 上)调用外部程序,考虑我的 Native
module 的 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"'
[1] git
似乎正在调用 sh
如下(使用带占位符的 sh
语法进行说明):
sh -c '<config-value> "$@"' '<config-value>' <git-supplied args>
也就是说,调用存储在配置值中的命令行时附加 git
提供的传递参数。请注意,第一个 post -c
参数再次是配置值,它绑定到 [=64=]
,即设置调用名称,因此 不是 传递参数数组的一部分,"$@"
。 git
提供的传递参数的一个示例是要编辑的文件的路径,它被传递到存储在 core.editor
配置值中的命令行。
[2] 与 所有 外部程序一起工作的解决方案在 Windows 上基本上是不可能的,因为每个程序都可以自行决定它如何解析对传递的参数进行编码的字符串。但是,ie
了解并适当应用了一些广泛使用的模式,这使得它可以与批处理文件和类似 msiexec
的可执行文件一起稳健地工作。