MSYS/MinGW 路径转换的规则是什么?

What is the rule of MSYS/MinGW path translation?

我一直在原生 Windows 环境下关注 this post on how to use Winmerge as a diff tool in git. Initially it doesn't work (ok now, therefore irrelevant to my question here). One key difference is I'm using git provided inside MSYS2, not the msysgit。相关的 git 配置片段是:

[diff]
        guitool = winmerge

[difftool "winmerge"]
        cmd = \"????/WinMergeU.exe\" /e /s /u /r /wl \"$LOCAL\" \"$REMOTE\"

令我震惊的是,winmerge的一些命令行选项在执行时被转换为盘符,导致失败。 git difftool -g之后真正执行的命令是:

"????\WinMergeU.exe" /e S:/ U:/ R:/ D:/msys64/wl <file1> <file2>

其中D:/msys64是我的MSYS2安装前缀。请注意错误中的不一致 — /e 未转换,/wl 转换为路径组件,所有其他转换为驱动器号。稍后通过使用 - 而不是 / 作为所有选项的前缀找到解决方案:

[difftool "winmerge"]
        cmd = \"????/WinMergeU.exe\" -e -s -u -r -wl \"$LOCAL\" \"$REMOTE\"

我的问题是:

  1. 为什么行为不一致?是否有关于 cygpath 如何执行路径转换的任何参考?
  2. 幸运的是 WinMerge 接受使用 - 作为选项指示器。对于那些只接受 / 的 GUI 工具,有什么解决方法吗?

我相信 MSYS2 试图按照 same behavior in MSYS 将 unix 路径参数转换为 Windows 可执行文件的路径,而不依赖于 msys2 dll。

在这种情况下,您可以将以单斜杠开头的参数转义为双斜杠,即

\"????/WinMergeU.exe\" //e //s //u //r //wl \"$LOCAL\" \"$REMOTE\"

规则(从链接页面中提取):

  • Arguments starting with a drive specifier (eg C:) are considered to be Windows paths and are not converted.
  • Arguments containing a ; are considered to be Windows path lists and are not converted.
  • An argument starting with 2 or more / is considered an escaped Windows style switch and will be passed with the leading / removed and all \ changed to /.
    • Except that if there is a / following the leading block of /, the argument is considered to be a UNC path and the leading / is not removed.
  • If an argument has a leading / followed by a drive specfier, the / is removed and all \ are changed to /.
  • If an argument has a = it is considered a variable assignment. The right hand side is converted according to these rules and the left hand side has all \ converted to /, unless the right hand side starts with a drive specifier.
  • An argument that doesn't start with -, ", ', or @ and contains a : followed by /, :, or .; and a / is considered a POSIX path list. Every :-separated element is converted according to these rules, and the : are replaced with ;. Any / are converted to \.
    • Unless the : is followed by //: then it is considered a URL and not converted.
  • An argument with a leading / is converted up to the first /...
  • If an argument has a leading - and a ,, the part after the , is converted according to these rules and the whole argument has \ converted to / unless the path starts with a drive specifier.
  • If an argument has a leading - and the second character is a /, the part from the / onward is converted according to these rules.
  • An argument with a leading @ is considered a response file argument and the text following the @ is converted according to these rules.
  • An argument inside ' or " is processed according to these rules with the quotes ignored.