正确设置 git 过滤器并在 Windows 中将参数传递给它

properly setting a git filter and passing parameters to it in Windows

我需要在 Windows.

下设置一个 git 过滤器 和一个可执行文件和一长串参数

可执行文件是jq.exe我需要传递给它的参数是--indent 1 "(.cells[] | select(has(\"outputs\")) | .outputs) = [] | (.cells[] | select(has(\"execution_count\")) | .execution_count) = null | .metadata = {\"language_info\": {\"name\": \"python\", \"pygments_lexer\": \"ipython3\"}} | .cells[].metadata = {}"

我尝试了两种方法让 git 过滤器调用这个长命令。 None 个有效。


  1. 我写了一个包含完整调用的小 bat 文件 nbstrip.bat。我把这个bat文件放在了路径中。我已经设置了过滤器 git config --global --add filter.nbstrip.clean "cmd /c nbstrip"

    当我使用 git add test.nb 间接调用此过滤器时,git 显然会 "confused" 并将过滤器的输出解释为新命令并尝试执行它们。

    在 git 过滤器中将 window bat 文件设置为命令的正确方法是什么?


  1. 为了简化命令调用,我把所有的参数都放在了一个辅助文件里%appdata%。这样 git config --global --add filter.nbstrip.clean "jq --indent 1 --from-file %appdata%\nbstrip.jq.txt".

    当我用 git add test.nb 间接调用此过滤器时,jq 可执行文件没有收到正确的文件名,并抱怨错误消息 jq.exe: Could not open C:UsersAdminAppDataRoamingnbstrip.jq.txt: No such file or directory 就好像它在名称被传递给可执行文件。

    在 git 过滤器命令规范中使用带反斜杠的参数的正确方法是什么?


注意:

您有任何其他策略可以解决这种情况吗?

这些命令被传递给shell(即Bash或Busybox sh),而不是cmd,所以你需要以适合Unix的方式编写它们shell.此外,Git for Windows 包含的 Bash 版本在参数以斜杠开头时有一些奇怪的行为:它认为它们是 Unix 路径,并将它们重写为 Windows 路径,除非它们以一个额外的斜杠开头(有关详细信息,请参阅 this answer)。

您应该将 cmd /c nbstrip 写成 cmd //c nbstrip,这样它就不会将“/c”解释为 "c:\"。您还可以将批处理脚本重写为 shell 脚本并直接调用它。

在第二种情况下,shell 将反斜杠视为转义字符,因此您需要引用它。此外,由于它被传递给 shell,您需要使用 shell 形式的环境变量。所以你会把它写成 jq --indent 1 --from-file "$appdata/nbstrip.jq.txt"。因为它有双引号,如果你从 Git Bash 调用它,你需要写 git config --global --add filter.nbstrip.clean 'jq --indent 1 --from-file "$appdata/nbstrip.jq.txt"'.

请注意,上面假设 appdata 指的是一个全局可访问的环境变量,而不是由 cmd 或 PowerShell 显式创建的。如果它实际上特定于那些环境,您可能需要使用不同的环境变量或技术来查找位置。

Git 即使在 Windows 上也使用 Unix shell,因为它是为 Unix 设计的,并且在不同的系统上具有不同的命令行为是不可取的。例如,如果它在 Windows 上使用 cmd,由于不兼容的行为,您将无法跨系统共享 .gitconfig 或其他配置。