每次提交时运行 shell 命令

问题描述 投票:0回答:3

我想浏览一系列提交并对每个提交执行 shell 命令。如果命令失败,我希望步行停止,否则继续前进。我已经看过了

filter-branch
,但我不想重写提交,只需检查它们即可。
for-each-ref
似乎不允许您指定要执行的范围。

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

git foreach origin/master..master 'git submodule update && make clean && make'

我当然可以编写一个 shell 脚本来执行此操作,但 git 似乎有一个很好的方法可以做到这一点。

git shell
3个回答
95
投票

您可以使用带有 exec 选项的交互式变基。

git rebase -i --exec <build command> <first sha you want to test>~

--exec <cmd>
在每行后面添加
exec <cmd>
,在最终历史记录中创建提交。
<cmd>
将被解释为一个或多个 shell 命令。

重新排序和编辑提交通常会创建未经测试的中间结果 脚步。您可能需要检查您的历史记录编辑是否没有中断 通过运行测试或至少在中间重新编译来进行任何操作 使用

exec
命令(快捷键
x
)查看历史记录中的点。

当命令失败时,交互式变基将停止(即退出 非 0 状态)给您一个解决问题的机会。


32
投票

您可能想要rev-list

#!/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")

然后你可以使用它

./test_commits.sh origin/master..master

10
投票

这是一个使用

xargs
的很酷的单行代码。

git rev-list @{upstream}..HEAD | xargs -n1 -I{} sh -c 'git checkout {} && git submodule update && make clean && make'

您可能还想将

--reverse
选项传递给 rev-list,以便最后一次结帐是 HEAD。

© www.soinside.com 2019 - 2024. All rights reserved.