--- topic: bisect source_keys: - git-scm-bisect-docs --- # Finding a commit with `git bisect` Read this when the question is *which commit changed the behaviour* and there is no string, file, or line range to search the log for. Binary search reduces the trials from O(N) to O(log N). ## Manual flow ```bash git bisect start git bisect bad [HEAD] # mark current (or specified) as broken git bisect good # mark known-good baseline # Git checks out the midpoint; test it git bisect good # test passes git bisect bad # test fails # Repeat until git reports "X is the first bad commit" git bisect reset # return to the original HEAD ``` ## Automated With a test command available, use `git bisect run `. Git reads the exit code: `0` good, `1`–`124` bad, `125` skip (build broken), `126`–`127` POSIX shell errors, treated as bad, and `128` or above aborts the session outright rather than marking the commit bad. ## Untestable commits `git bisect skip` excludes a commit that cannot be built or tested without deciding good or bad for it. When the first bad commit is adjacent to a skipped range, bisect reports that it cannot pinpoint the culprit and lists the candidates — that is the precise answer the skip range allows, not a failure. ## Undoing a wrong good/bad call `git bisect log` prints the session's decision history. Save it, edit out the mistaken entry, and resume from the corrected log rather than restarting the search: ```bash git bisect log > bisect.log # edit bisect.log, removing the wrong decision git bisect reset && git bisect replay bisect.log ``` ## Narrowing and speeding up - `git bisect start HEAD v1.2 -- src/` restricts bisection to a path, cutting the trial count. - `--no-checkout` updates the `BISECT_HEAD` ref instead of checking out a working tree — useful for tests that do not need one, and automatic in bare repos. - `--first-parent` follows only first parents at merges, finding the integration commit that introduced a regression while ignoring broken side branches. ## Inspecting the remaining candidates `git bisect visualize` (alias `view`) opens the suspects in gitk, falling back to `git log` when no graphical display is detected. Add `--stat` or `-p` for a diffstat or full patches. ## Hunting a non-bug property change `git bisect start --term-new --term-old ` searches for any property change — a performance regression, say — instead of a bug. Use the custom terms in place of `good` and `bad` for the rest of the session. Once the first bad commit is identified, return to Step 3 to act on it and Step 4 to report it.