Find most recent good commit to pass to git bisect

Suppose I suddenly see something is failing on my Git repo. But I know that it was working a few commits ago, I just don’t remember which commit. Instead of trying to find a “good” commit to do a git bisect, I would like to ask Git (perhaps with a bash script), what is the most recent “good” commit?

Another reason not to just choose a commit from a while ago and use it as good is because in my repo there are many bad and good commits mixed together. It’s not linear.

  • remove deleted files from git: Argument list too long
  • Bash in Git for Windows: Weirdness when running a command with CMD.exe /C with args
  • How do I disable being able to set the git commit message from the command line?
  • In Git how can I stage a file I have just diffed without manually specifying the file?
  • Bash function to find all Git commits in which a file (whose name matches a regex) has *changed*
  • Git post-receive hook not working
  • So how can I loop, starting with the most recent commit and going as long as necessary, executing a command that returns 1 if bad 0 if good?

  • How to display available branches in Android source tree?
  • What is “git” syntax for getting just the unified diff of how a single commit X changed a single file Y?
  • Git - remove commits with empty changeset using filter-branch
  • Getting fatal: object is corrupted when pushing to a remote repo
  • How to run a shell command in ansible's check mode?
  • How to fetch no of commits made by developer for a day in Git repository for a particular branch
  • One Solution collect form web for “Find most recent good commit to pass to git bisect”

    while ! good-or-bad-test-command ; do
       git checkout HEAD^
    done
    

    However, if the breakage is within just the last few commits somewhere, you can do this manually.

    $ good-or-bad-test-command
    # if it fails, then:
    $ git checkout HEAD^ # pop to previous
    $ good-or-bad-test-command # <-- recalled by hitting up arrow in bash
    # still fails:
    $ git checkout HEAD^ # <-- recalled with up arrow
    $ good-or-bad-test-command # <-- recalled
    ...
    

    thanks to history recall, it will take fewer keystrokes than banging out a loop.

    git checkout avoids moving your branch HEAD, putting you in a “detached state” from which you can easily recover with git checkout <yourbranch>.

    [Edit, March 2017]

    But, the question is, why would you still use git bisect in this situation? You’ve linearly searched through the bad commits back to the good one; there is no need to do another binary search for the same info.

    It may be fewer steps to just take a guess to find some commit that is still good, and get git bisect going.

    If you suspect you recently broke something, just go back 16 commits. Or 32 or whatever. Go back to the last tagged release. The binary search will quickly zero in:

    $ git bisect start
    $ git bisect bad # HEAD known to bad; almost always the case
    $ git checkout HEAD~8  # wild guess; almost certainly before breakage
    $ good-or-bad-test-command # check: is it really good?
    $ # if not, git checkout HEAD~8 # go back more, repeat test
    $ git bisect good  # bisect begins
    

    If we have a git with a very long history, and discover something had broken a long time ago (something previously untested which is now tested), we can probe backwards exponentially to find a good commit: git checkout HEAD~16; then if that’s not good, git checkout HEAD~32; then git checkout HEAD~64.

    That’s the general strategy for binary searching through an unknown-range. Don’t linearly scan to determine the range, because that makes the algorithm linear. If we exponentially extend the range, we keep it logarithmic.

    Git Baby is a git and github fan, let's start git clone.