Git bisect

KDE is supposed to move over to git and there has been lots of discussion and blog posts about that lately. Now it is on me to provide a small post myself. Those that know git bisect can skip this one.

Git bisect is a great tool that saved my day several times already and again just today, shortly before the release of KDE 4.4 SC. In short git bisect is there to find faulty commits.

Often when developing you encounter bugs where you know that it worked many revisions ago, but how do you find the revision that introduced the bug? When using git a few commands are enough:

  1. start it: git bisect start
  2. tell git which version is bad: git bisect bad {sha1/tag}?
  3. tell git which version is good: git bisect good {sha1/tag}?
  4. end it: git bisect reset

Basically that is all you need to know and here is an example session (I was at master):

  1. git bisect start
  2. git bisect bad //latest commit is bad
  3. git bisect good 73ea4b2fd5ae39993009dd765c6ff562ceec09da//this commit is good
  4. XY revisions left to test after this (roughly Z steps)
  5. recompiling
  6. testing
  7. either git bisect bad or git bisect good depending if it did not work or if it did work
  8. go to 4 or 9
  9. d4f650537917441fcfd3aa71e0c646b8fc7464ec is the first bad commit//yeah it was me who did crap 😉
  10. git reset
  11. Fix and commit

That process is very fast as git uses bisecting as the name suggests e.g. there are 100 commits, 1 is working 100 not, now it checks commit 50, if it works it is checking commit 75 otherwise commit 25 …

Whee and another really stupid and bad bug that was only triggered ocassionally bites the dust.

Baseline? Using git bisect when a commit is wrong or even better use test-cases to avoid wrong commits in the first place.

Advertisements

Tags: , ,

10 Responses to “Git bisect”

  1. Larry Garfield Says:

    How ironic! I just posted a very similar article myself a few days ago. bisect really is quite slick.

  2. Spart Says:

    the problem when you work on a large repository, is the insane compile time for each bisection.

    With current git bisect implementation, it isn’t really worth it on something as large as e.g. kdelibs (my experience from git-svn) because it only checks out whole states (unless I missed something, which is not unlikely :-).

    If for instance you know the commit you are looking for only affects a subdirectory, and you know you don’t need to recompile the whole project to find the culprit, you might be better off using checkout in this way:

    git checkout xxxxxxxxxxxx — name_of_subdirectory/

    that will only checkout files under name_of_subdirectory/
    then recompiling/installing this limited subset will only take a few moments.
    Of course, you have the inconvenience of having to calculate the bisection manually, but it’s not like it’s rocket science…

    Still in any cases, you often end up losing your stashes (cf. git-stash) in mysterious ways in the process, so better back them up.

    • mat69 Says:

      That is not really a problem as Mark Kretschmann pointed out.

      In my case it was kdenetwork, recompiling it every time would take long as well so I did it this way:
      cd kget/ && cmakekde && kbuildsyoca4 && cd ../ && kget
      as it was about a bug in KGet and then either
      git bisect good
      or
      git bisect bad
      where cmakekde is a bash-function that calls cmake etc.

      • Spart Says:

        This would work for kget because in kdenetwork, every subdirectory is more or less independent of the others.

        When it’s not the case, you still need to rebuild any dependency that changed between two bisection, and a compiler cache won’t help you much in that case ;-(

  3. maninalift Says:

    Don’t forget to use the right maths words to sound cleaver: git bisect locates the bug *in logarithmic time*

    :¬)

    • mat69 Says:

      I would not say logarithmic time, as the compilation time could be different, rather in log(n) steps. 😛

      Though in my experience it is more than round(log(n) + 0.5).

  4. Mark Kretschmann Says:

    @Spart:

    Using “ccache” can drastically reduce these (re)compile times:

    http://ccache.samba.org/

    Regards, Mark.

    • Spart Says:

      of course it helps. It doesn’t do much good though when some core header you depend on changes (which is my point here).

  5. Esben Mose Hansen Says:

    @spart: Never tried it, but git does support bisecting on one path:

    Cutting down bisection by giving more parameters to bisect start
    You can further cut down the number of trials, if you know what part of the tree is involved in the problem you are tracking down, by specifying path parameters when issuing the bisect start command:

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

    • Spart Says:

      I think I tried that, but IIRC, it just prunes the commits that don’t contain the path you give. IOW, it reduces the number of commits to look at, but each checkout is still complete.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: