Description 450 -> 266 chars, body 1044 -> 462 words. The bisect procedure moves to references/bisect.md. The boundary clause read 'not writing or rewriting commits', which disclaimed the cherry-pick and revert this skill's own Step 3 executes; it now excludes authoring and rebasing only. Adds 'backport' so cherry-pick is reachable by natural language at all, accepting 266 chars against a 250 soft target and a 400 ceiling.
69 lines
2.6 KiB
Markdown
69 lines
2.6 KiB
Markdown
---
|
||
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 <commit> # 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 <cmd>`. 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 <new> --term-old <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.
|