正确设置 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 个有效。
我写了一个包含完整调用的小 bat 文件 nbstrip.bat
。我把这个bat文件放在了路径中。我已经设置了过滤器 git config --global --add filter.nbstrip.clean "cmd /c nbstrip"
当我使用 git add test.nb
间接调用此过滤器时,git 显然会 "confused" 并将过滤器的输出解释为新命令并尝试执行它们。
在 git 过滤器中将 window bat 文件设置为命令的正确方法是什么?
为了简化命令调用,我把所有的参数都放在了一个辅助文件里%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 过滤器命令规范中使用带反斜杠的参数的正确方法是什么?
注意:
- 在这两种情况下,我都尝试过直接在命令行中调用命令,它们运行良好
- .git 属性和 git 配置中的 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
或其他配置。
我需要在 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 个有效。
我写了一个包含完整调用的小 bat 文件
nbstrip.bat
。我把这个bat文件放在了路径中。我已经设置了过滤器git config --global --add filter.nbstrip.clean "cmd /c nbstrip"
当我使用
git add test.nb
间接调用此过滤器时,git 显然会 "confused" 并将过滤器的输出解释为新命令并尝试执行它们。在 git 过滤器中将 window bat 文件设置为命令的正确方法是什么?
为了简化命令调用,我把所有的参数都放在了一个辅助文件里
%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 过滤器命令规范中使用带反斜杠的参数的正确方法是什么?
注意:
- 在这两种情况下,我都尝试过直接在命令行中调用命令,它们运行良好
- .git 属性和 git 配置中的 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
或其他配置。