如何修复这个 git 自动化脚本?

如何修复这个 git 自动化脚本?

我有这个简单的脚本可以自动化git status许多 git 存储库:

@ECHO OFF

for /D %%s in (C:\Projects\*) do (
    set HasChangesCommand=git -C %%s status --porcelain | findstr . && echo 1 || echo 0
    set IsAheadCommand=git -C %%s status --porcelain | findstr ahead && echo 1 || echo 0
    set IsDiveregedCommand=git -C %%s status --porcelain | findstr diverged && echo 1 || echo 0
    if "%HasChangesCommand%" == "1" (
        call Info %%s;
        git -C %%s status --porcelain
        echo.
    ) else if "%IsAheadCommand%" == "1" (
        call Warning Push %%s
    ) else if "%IsDiveregedCommand%" == "1" (
        call Warning Sync %%s
    )
    call Info %HasChanges%
)

基本上,我想分析每个目录的输出git status,并根据输出显示更简单的消息。

但它不起作用。

我猜我在运行块命令时遇到了问题if else

我做错了什么?

答案1

你至少有两个问题:

  1. Cmd.exe 的工作方式是,整个中的所有变量do ( ... )都会被扩展立刻,就像它只是一个单行命令一样——实际上每次迭代都不会重复扩展。这意味着使用所做的任何更改set都不会产生任何效果。

    您需要使用延迟扩展!var!或将循环重写为call:子例程而不是直接(...)块。

    (更好的是,用 PowerShell 或 Bash 或其他没有此问题的语言重写脚本。)

  2. 你没有把“git”命令的输出放在变量中——而是把命令他们自己在变量中。例如,"%HasChangesCommand%:包含文字文本"git -C project1 status...",当然它永远不会与相等"0"

    要将命令的输出捕获到变量中,您需要for /f在 Cmd 或$(…)Sh/Bash shell 中使用。例如:

    Cmd:     for /f "tokens=*" %%a in ('git -C project1 status') do set HasChangesResult=%%a
    
    Bash:    HasChangesResult=$(git -C project1 status && echo 0 || echo 1)
    

    但在这种情况下,您实际上不需要输出,因为您可以直接通过%ERRORLEVEL%Cmd(或类似地$?在 Bash 中)获取退出状态:

    Cmd:     git -C project1 status
             set HasChangesResult=%ERRORLEVEL%
    
    Bash:    git -C project1 status
             HasChangesResult=$?
    
  3. 与上一个问题相关,即使像 这样的操作符||与 在同一行中使用,它们仍被视为操作符set=- 它们实际上不会成为值的一部分。例如,此命令:

    set HasChangesCommand=git -C %%s status --porcelain | findstr . && echo 1 || echo 0
    

    可以(在心理上)分为:

    (set HasChangesCommand=git -C %%s status --porcelain | findstr .)
    && echo 1
    || echo 0
    

    换句话说,由于set命令成功执行,因此调用 echo。

相关内容