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

StackOverflow https://stackoverflow.com/questions/18786881

  •  28-06-2022
  •  | 
  •  

Question

I have a bug that have been introduced a long time ago, and testing for it is painful. However, I strongly suspect that changes which introduced the bug happened in one particular source code file.

Can I run git bisect on a sub-set of commits that changed that one file?

Était-ce utile?

La solution

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

Autres conseils

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

One technique is to create a temporary branch starting back at a known good location and simply copy across all [i.e. a script] the commits that touch that file, and then do a bisect on that temporay branch. That way you skip all the irrelevant commits.

This was discussed on the Git Mailing List within the last month or so $gmane/232114. The discussion did not identify an easy way to pre-skip commits that had no relevant changes (It's probably something that would be useful though - as they say, patches welcome)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top