Git run shell command for each commit

GitShell

Git Problem Overview


I would like to walk through a range of commits and perform a shell command on each. If the command fails, I would like the walk to stop, otherwise keep going. I have looked at filter-branch, but I don't want to re-write the commits, just check them out. for-each-ref does not seem to allow you to specify a range to act on.

My specific problem is that I created a bunch of commits and I would like to ensure that each commit is buildable. I would like to do something like:

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

I could of course write a shell script to do this, but it seems like the sort of thing that git might have a nice way to do.

Git Solutions


Solution 1 - Git

You can use interactive rebase with an exec option.

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

> --exec Append "exec " after each line creating a commit in the final history. will be interpreted as one or more shell > commands. > > > Reordering and editing commits usually creates untested intermediate > steps. You may want to check that your history editing did not break > anything by running a test, or at least recompiling at intermediate > points in history by using the "exec" command (shortcut "x"). > > The interactive rebase will stop when a command fails (i.e. exits with > non-0 status) to give you an opportunity to fix the problem.

Solution 2 - Git

You probably want 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")

Then you can use it with

./test_commits.sh origin/master..master

Solution 3 - Git

Here's a cool one-liner using xargs.

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

You may also want to pass the --reverse option to rev-list so that the last checkout is HEAD.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFazJaxtonView Question on Stackoverflow
Solution 1 - GitAndrew CView Answer on Stackoverflow
Solution 2 - GitJustin HowardView Answer on Stackoverflow
Solution 3 - GitCody Allan TaylorView Answer on Stackoverflow