每次提交都运行git run shell命令

Faz*_*ton 43 git shell

我想介绍一系列提交并对每个提交执行shell命令.如果命令失败,我希望步行停止,否则继续前进.我已经看了filter-branch,但我不想重写提交,只是检查出来. for-each-ref似乎不允许您指定要操作的范围.

我的具体问题是我创建了一堆提交,我想确保每个提交都是可构建的.我想做的事情如下:

git foreach origin/master..master 'git submodule update && make clean && make'
Run Code Online (Sandbox Code Playgroud)

我当然可以编写一个shell脚本来执行此操作,但看起来git可能有一个很好的方法.

And*_*w C 50

您可以将交互式rebase与exec选项一起使用.

git rebase -i --exec <build command> <first sha you want to test>~
Run Code Online (Sandbox Code Playgroud)

--exec在每行创建最终历史记录中的提交后附加"exec".将被解释为一个或多个shell命令.

重新排序和编辑提交通常会创建未经测试的中间步骤.您可能希望通过运行测试来检查历史编辑没有破坏任何内容,或者至少使用"exec"命令(快捷键"x")在历史记录的中间点重新编译.

当命令失败时(即退出非0状态),交互式rebase将停止,以便您有机会解决问题.

  • 它就像HEAD~1,它说要再往前走,所以你实际上拿起了你要测试的SHA.标准git修订版规范 (2认同)

Jus*_*ard 23

你可能想要转发列表.

#!/usr/bin/env bash
# test_commits.sh

while read -r rev; do
    git checkout "$rev"
    if ! git submodule update && make clean && make; then
        >&2 echo "Commit $rev failed"
        exit 1
    fi
done < <(git rev-list "$1")
Run Code Online (Sandbox Code Playgroud)

然后你可以使用它

./test_commits.sh origin/master..master
Run Code Online (Sandbox Code Playgroud)

  • 需要更多引号以避免字符串拆分和glob扩展.``$ 1"`,``$ rev``等.在字符串拆分之前收集来自`git rev-list`的所有输出并迭代它们也意味着比在读取-r rev时更多的前期延迟; 做......; 完成<<(git rev-list"$ 1")`,在读取内容时流入内容,而不是收集整个流并在前面解析它.(出于显而易见的原因,这种方法对于非常大的修订列表也更具内存效率). (4认同)
  • (也就是说,虽然围绕shell最佳实践有改进的余地,但这绝对是最好的答案,而且我的+1). (2认同)

Cod*_*lor 7

这是使用xargs.

git rev-list @{upstream}..HEAD | xargs -n1 -I{} sh -c 'git checkout {} && git submodule update && make clean && make'
Run Code Online (Sandbox Code Playgroud)

您可能还想将--reverse选项传递给 rev-list,以便最后一次结帐是 HEAD。