Skip to main content
RunBook Academy

Git, CI/CD & GitOpsXXIV · BisectBisect

Bisect log and visualize — recording, inspecting, and replaying a session

Advanced⏱ ~18 mingit

What you'll learn

  • Read a `git bisect log` output and reconstruct the session from it
  • Use `git bisect visualize` to inspect the candidate topology as a DAG
  • Save a bisect log to a file and replay it later with `git bisect replay`
  • Identify when the log reveals a wrong boundary or a wrong test
  • Diff two bisect sessions by reading their logs side by side

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

A bisect session is a series of state transitions: each git bisect good, git bisect bad, or git bisect skip command moves the session forward by one step. After the session ends, the engineer has the conclusion (the first bad commit) but not the trail that led to it. The trail matters when the conclusion seems wrong, when the engineer wants to compare two sessions, or when a teammate needs to re-run the same session against a different branch. The mechanisms that preserve the trail are git bisect log (record), git bisect visualize (inspect), and git bisect replay <logfile> (re-execute).

What git bisect log captures

git bisect log writes every command run during the session to stdout, in the order they were run, as a shell script that can re-create the session. The output includes the initial boundaries, every midpoint marking, and every skip. Running the output of git bisect log through git bisect replay reproduces the session exactly.

# A session in progress
git bisect log
# git bisect start
# git bisect bad HEAD
# git bisect good v3.4.0
# git bisect good a3f1c2d3b4
# git bisect bad 7e89b40c1d
# git bisect skip 1c0d3f5e2a
# # only skipping 1 commit
# git bisect good 9b2a814f0c

The log is a shell script. The lines that begin with # are comments preserved by the original session (the engineer can add them by editing the output, or git bisect log writes them when the engineer runs git bisect skip with a reason). The non-comment lines are commands. Running them under git bisect replay re-creates the session step by step.

# Save and replay
git bisect log > /tmp/bisect-session.log
git bisect reset
# Later, on a different branch or after a fresh clone:
git bisect replay /tmp/bisect-session.log

The replay mechanism is the operational answer to “we found the regression on the staging branch; let me reproduce the bisect on the production branch”. Save the log, switch branches, replay, and the conclusion arrives in a fraction of the original cost.

git bisect visualize

git bisect visualize opens a graphical viewer (gitk by default, or whatever git config sequence.editor and the related viewer configuration specifies) showing the current candidate DAG with the good, bad, and skip markings rendered as colors on the commit nodes. The visualization is the right tool when the candidate set is a DAG with merge commits, when the engineer wants to see the topology the bisect is actually walking, or when a wrong conclusion needs debugging.

# Inspect the topology
git bisect visualize
# Opens gitk showing the candidate set, color-coded by marking
flowchart TB
    subgraph GOOD["good boundary"]
        G["v3.4.0"]
    end
    subgraph MID["candidate set"]
        M1["9b2a814"]
        M2["1c0d3f5 (skipped)"]
        M3["7e89b40 (bad)"]
        M4["a3f1c2d (good)"]
        M5["HEAD (bad)"]
    end
    subgraph FOUND["first bad"]
        F["7e89b40"]
    end
    G --> M1
    M1 --> M2
    M2 --> M3
    M3 --> M4
    M4 --> M5
    M3 -.-> F

The visualization shows three things the log does not: the spatial relationship between midpoints, the parents of merge commits that might not be in the linear range, and the skip commits that are off the main path. An engineer who looks at the visualization and sees a skip on a merge commit understands immediately why the bisect took more than the minimum number of steps - the skip is a midpoint that bisect could not narrow through and had to work around.

Replaying a saved session

git bisect replay <logfile> re-executes the commands in the log against the current repository state. The replay requires that the commits referenced in the log still exist in the object database (the engineer has fetched them) and that the boundaries still make sense (the good boundary is still verifiably good, the bad boundary still exhibits the regression). If those conditions hold, the replay arrives at the same conclusion the original session arrived at.

# Typical replay workflow
git checkout feature/observability
git fetch origin
git bisect start
git bisect replay ~/bisect-sessions/2024-01-15.log
# Replaying: 5 revisions left to test after this (roughly)
# ...
# 7e89b40 is the first bad commit
git bisect reset

The replay mechanism also enables replay with modifications. An engineer who spots a wrong marking in the log can edit the log (flip a good to bad, change a skip to good), save the edited log, and replay it. The resulting session arrives at a different conclusion, derived from the corrected markings. This is the canonical way to “fix” a concluded bisect without re-running it from scratch.

What to look for when the conclusion is wrong

A bisect conclusion that identifies a surprising commit is either the result of a wrong boundary, a wrong test, or a wrong marking. The bisect log distinguishes these cases.

# A log that reveals a wrong boundary
git bisect log
# git bisect start
# git bisect bad HEAD
# git bisect good v3.0.0       # <-- the boundary is 6 months old
# git bisect good a3f1c2d3
# git bisect bad 7e89b40c1
# ...
# Conclusion: 7e89b40 is the first bad commit

A boundary that is far from the actual regression produces a bisect that walks a much larger range than necessary, and the conclusion might be a commit that introduced an unrelated regression that happened to be earlier. The fix is a tighter good boundary.

# A log that reveals a wrong marking
git bisect log
# git bisect start
# git bisect bad HEAD
# git bisect good v3.4.0
# git bisect bad a3f1c2d3     # <-- should have been good
# ...
# Conclusion: 1c0d3f5 is the first bad commit

A wrong marking (marking a midpoint bad when it should have been good, or vice versa) propagates forward: every subsequent midpoint is selected against the wrong hypothesis. The conclusion is still “the first bad commit in the marked range”, but the marked range is now mis-aligned with the truth. The fix is to edit the log and replay.

Production discipline

  1. Always save the log of a concluded bisect. The conclusion is the deliverable, but the log is the audit trail. Save it alongside the bug ticket, the PR, the incident report.
  2. Use git bisect visualize whenever the candidate set has merge commits. The log is a linear sequence; the visualization shows the DAG. An engineer who reads only the log on a DAG-rich history might miss a skip on a merge commit and wonder why the conclusion is off.
  3. Replay, do not re-run, when re-bisecting the same regression. If the engineer needs the bisect against a different branch or a fresh clone, replay the saved log. Re-running with the same commands is fine but is unnecessary work.
  4. Treat a wrong conclusion as a hypothesis about the test. A surprising first bad commit usually means a wrong test (the test is flaky at some midpoints), not a bug in bisect. Read the log; look for markings that contradict the engineer’s understanding of the test.

Cross-course references

  • CI/CD Pipeline Patterns - Part XI (Reproducibility) covers the discipline of saving the inputs to a CI run so it can be re-run identically. The bisect log is the same discipline for regression-hunting sessions.
  • Linux for Production Sysadmins - Part XXIV (BisectingKernels) describes the kernel community’s bisect.log practice of attaching the log to the bug report so other developers can replay the session.
  • Performance Engineering for Production Sysadmins - Part VI (ProfilingArtefacts) covers saving the inputs to a profiling run so the run can be re-analysed later; the bisect log is the version-control-domain instance of the same pattern.

Quiz

Knowledge check · 4 questions

  1. Q1. What does `git bisect replay &lt;logfile&gt;` do, and when is it useful?

  2. Q2. `git bisect log` produces a JSON object that must be parsed by a separate tool; running it through `git bisect replay` does not reproduce the session.

  3. Q3. Name the three inspection tools available during a bisect session, and identify which one answers a question of reproducibility versus topology.

  4. Q4. Diagnose why the bisect conclusion is wrong, and identify the steps to correct it.

    An engineer runs a bisect over 200 commits and concludes that commit `a3f1c2d` is the first bad commit. The diff for `a3f1c2d` is a typo fix in a comment - it cannot have introduced a regression. The engineer reads the saved `bisect-session.log` and finds a marking they do not understand: at midpoint `9b2a814`, the log says `git bisect bad 9b2a814`. The engineer's recollection is that `9b2a814` was a green commit.

Passing score: 75%. Answers are checked in this browser.