skip to content

In Git, when should you use git bisect skip, and how does it change the result?

level: seniorimportance: should knowfreq 30%

answer

  1. for commits you cannot judge
  2. never guess an answer instead
  3. costs you clean halving
  4. ranges can be skipped at once
  5. result may become a candidate list

basics

~20 s

Use git bisect skip when a candidate commit cannot be judged, typically because it does not build. Git then tests a neighbour, and if only skipped commits remain it reports a set of possible first bad commits instead of one.

solid answer

~40 s

`git bisect skip` says you cannot judge this commit — it does not build, the test harness is missing, or the symptom is masked by an unrelated breakage. Git records the commit as untestable and chooses another candidate nearby rather than halving cleanly, so skips cost you steps. You can skip a whole range, for example `git bisect skip v2.5..v2.6`, when you know a stretch of history is broken. The risk shows up at the end: if every remaining candidate was skipped, Git cannot name a single culprit and instead reports that only skipped commits are left, listing the commits the first bad one could be. Recovering means making those commits testable — building differently, testing a narrower symptom, or applying a small fix on top of each candidate — rather than guessing.

code

console · 8 lines
console
$ git bisect skip
Bisecting: 5 revisions left to test after this (roughly 3 steps)
$ git bisect skip v2.5..v2.6
...
There are only 'skip'ped commits left to test.
The first bad commit could be any of:
2f1c9a1 build: split the parser module
7b3d40e parser: rename the token table

go deeper

for a junior

Remember that git bisect skip is the answer for a commit you cannot test, most often because it will not build, and that it keeps the session going.

for a middle

Explain that skipping makes Git pick a neighbouring candidate instead of halving cleanly, that ranges can be skipped at once, and that a script exit code of 125 is the automated equivalent.

for a senior

Show how you avoid the ambiguous ending: choose a symptom testable across the range, patch the build on top of candidates, limit by path, and use bisect log and replay to correct a messy session.

for a principal

Treat frequent skips as a signal about the repository: if history is routinely unbuildable, argue for per-commit CI and merge policies so diagnosis does not depend on archaeology.

## What skip means Bisect asks a binary question at every step, and `git bisect skip` is the escape hatch for a step you cannot answer. Typical reasons: the commit does not compile, a dependency of that era is unavailable, the test harness did not exist yet, or a second unrelated bug masks the symptom you are chasing. Answering good or bad anyway is the worst option — a single wrong answer discards the half containing the real culprit and the search converges confidently on an innocent commit. ## What Git does with a skip When you skip, Git marks that commit untestable and picks another candidate from the remaining range — usually adjacent to the one you skipped. That is why skipping degrades efficiency: a clean bisect halves the range each step, but skips move you sideways. In an automated search the same thing is triggered by a script exiting `125`, which is the run-mode spelling of skip. You can skip in bulk. `git bisect skip <rev1>..<rev2>` marks a whole range untestable, which is useful when you know a refactor left the tree unbuildable for a stretch of history. Remember the range excludes the first endpoint itself, so include the boundary commit deliberately if it is also broken. ## The ambiguous outcome The cost shows up at the end. If the search narrows to a set where every remaining candidate has been skipped, Git cannot identify a single boundary. Instead of `<sha> is the first bad commit` it reports that only skipped commits are left to test and lists the commits the first bad one could be. That is an honest answer, not a failure — but it leaves you with a set to inspect by hand. ## Getting to a single answer anyway Senior practice is to attack the untestability rather than accept the ambiguity: - **Test a different symptom.** If the real reproducer needs a build that fails at that commit, find a cheaper observable — a source-level check, a test that still compiles — that tracks the same change. - **Make the commit testable.** Apply the small fix that unbreaks the build on top of each candidate, run the test, then reset the tree before answering. The answer still applies to the candidate because the fix is unrelated to the symptom. - **Limit the search.** `git bisect start -- <path>` restricts candidates to commits touching the relevant paths, which often routes the search around the broken stretch entirely. - **Follow only the mainline.** Recent Git supports `git bisect start --first-parent`, which stays on first-parent commits and avoids descending into individual commits of merged topic branches that were never expected to build alone. It identifies the merge that brought the bug in rather than a commit inside the branch. ## Not the same as reset or abort `git bisect skip` continues the session; `git bisect reset` ends it and restores your branch. In automated runs, exit codes `128` and above abort the whole search, which is the right signal when the environment, not the commit, is at fault. ## Keeping the session recoverable Because skips make sessions longer and messier, keep the audit trail: `git bisect log` prints every answer including skips, and `git bisect replay <file>` re-runs an edited log. If you later learn a skipped commit was testable, edit the log and replay rather than restarting from scratch.

  • Why is skipping better than guessing good or bad on a commit you cannot build?
    Because bisect trusts your answers absolutely. A wrong answer removes the half of history that contains the culprit, and the search still terminates — with an innocent commit named as the first bad one. Skipping only costs efficiency and, at worst, yields a small candidate set you can inspect, which is a recoverable outcome.
  • How do you finish a search that ended with several possible first bad commits?
    Inspect the listed commits by hand — usually a handful with small diffs. Better, make them testable: apply an unrelated build fix on top of each, or switch to a cheaper symptom that compiles at that point, then answer properly. A path-limited restart via git bisect start -- <path> often avoids the broken stretch altogether.
  • When does bisecting only first-parent commits help?
    When history is a series of merged topic branches whose individual commits were never expected to build. Recent Git's git bisect start --first-parent keeps the search on the mainline, so it names the merge that introduced the regression instead of wandering into a half-finished commit inside a branch.

saying these in an interview costs you the question

  • Marks an unbuildable commit bad just to move on
  • Thinks skip ends the bisect session
  • Believes bisect always names exactly one commit
  • Confuses skip with reset or with aborting the run
  • Skips broadly without trying to make commits testable

context