How do I run git bisect only on commits that changed a certain file?

Yes, you can. In the manpage, you find this line:

git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>]
      [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]

so after --, you put the paths of the files or directories.

For example:

git bisect start -- arch/i386 include/asm-i386

Git bisect allows you to avoid testing a commit (see "Avoiding testing a commit" in the man page): when you are bisecting, and git has chosen a commit for you to test, you can override its choice with git reset --hard <commit you want>.

Using git log, you can find the last commit that affected a file (or subdirectory) - this will return its hash:

git log -1 --pretty=format:%H -- path_that_you_are_interested_in

So, every time git bisect suggests you a commit to test, you should run this command to ensure that you only test the commits that affected somepath:

git reset --hard $(git log -1 --pretty=format:%H -- somepath)

Now, there is one more thing that we need to take care of. If there are no interesting commits (i.e. no commits that modify somepath) between last checked good commit and the commit currently chosen by git bisect, we may end up in a loop. To avoid this, we should use a conditional clause:

#!/bin/bash

last_good=$(git bisect log | tail -1 | sed 's/git bisect good //')
last_interesting=$(git log -1 --pretty=format:%H -- lily/)

if [ "$last_good" == "$last_interesting" ]; then
    # there are no commits modifying somepath between previously
    # tested and currently checked-out one, so it must be good
    git bisect good
else 
    git reset --hard $(git log -1 --pretty=format:%H -- somepath)
fi

Tags:

Git

Git Bisect