LinuxCommandLibrary

git-bisect

Find the commit introducing a regression

TLDR

Start a bisect session on a commit range bounded by a known buggy commit, and a known clean (typically older) one

$ git bisect start [bad_commit] [good_commit]
copy

For each commit that git bisect selects, mark it as "bad" or "good" after testing it for the issue
$ git bisect [good|bad]
copy

After git bisect pinpoints the faulty commit, end the bisect session and return to the previous branch
$ git bisect reset
copy

Skip a commit during a bisect (e.g. one that fails the tests due to a different issue)
$ git bisect skip
copy

Display a log of what has been done so far
$ git bisect log
copy

SYNOPSIS

git bisect <subcommand> [options]

PARAMETERS

start
    Initiates a new bisect session. You typically follow this by marking a known bad commit and a known good commit to define the search range.

bad [<commit>]
    Marks the current or specified commit as 'bad' (i.e., containing the bug). This is often your starting point (e.g., HEAD).

good [<commit>]
    Marks the current or specified commit as 'good' (i.e., not containing the bug). This should be a commit known to be stable or bug-free.

reset [<commit>]
    Resets the bisect session, returning your repository to the branch that was checked out before git bisect start. Optionally checks out a specific commit after resetting.

skip <commit>...
    Marks one or more commits as untestable (e.g., due to build failures or unrelated issues) and excludes them from the search. Git will then pick another commit.

run <command>...
    Automates the bisect process by executing a specified script or command for each chosen commit. The script's exit code determines if the commit is good (0), bad (1-127, except 125), or skip (125).

log
    Displays the bisect log, showing the sequence of good/bad/skip marks and the current state of the bisect.

view / visualize
    Launches gitk (if available) to visually represent the bisect history, or shows a text-based log if gitk is not found.

DESCRIPTION

git bisect is a powerful debugging tool that uses a binary search algorithm to efficiently find the commit that introduced a regression or bug, or when a feature was added. By iteratively narrowing down the range between a known good commit (where the bug did not exist) and a known bad commit (where the bug exists), it drastically reduces the search space. The user is prompted to test a commit and mark it as "good" or "bad" (or "skip" if untestable), and git bisect automatically selects the next commit to test. This process continues until the exact culprit commit is identified, significantly reducing the time spent manually checking history.

CAVEATS

The effectiveness of git bisect relies on a clear definition of 'good' and 'bad' states. Automated 'run' requires a robust test script that exits with specific codes. The process can be complicated by very messy or complex merge histories. Skipping too many commits can reduce efficiency or inadvertently obscure the true culprit.

HOW IT WORKS

git bisect operates on a binary search principle. You initiate the process by providing a known bad commit (where the bug exists) and a known good commit (where the bug is absent). Git then checks out a commit roughly halfway between the good and bad commits. You test this checked-out code and inform Git whether it's good or bad. Based on your input, Git halves the remaining search space and checks out another middle commit. This iterative process continues until only one commit remains, which is then identified as the first bad commit (the one that introduced the bug).

TYPICAL MANUAL WORKFLOW

1. git bisect start
Start the bisect session.

2. git bisect bad <bad_commit_hash_or_ref>
Tell Git the commit where the bug definitely exists (e.g., your current HEAD or a release where the bug is present).

3. git bisect good <good_commit_hash_or_ref>
Tell Git a commit where the bug definitely did not exist (e.g., an older release tag or a known stable point).

4. Git checks out an intermediate commit. Test the code at this commit to see if the bug is present.

5. If the bug is present: git bisect bad
If the bug is not present: git bisect good
Repeat steps 4-5 until Git identifies the culprit commit.

6. After the culprit is found and reported: git bisect reset
Exit the bisect session and return to your original branch.

HISTORY

git bisect has been a core utility within Git since its early development. It leverages Git's fundamental commit graph and history tracking capabilities to provide an efficient and powerful debugging workflow. Its inclusion from early on signifies its importance in practical software development and maintenance, demonstrating Git's capabilities beyond mere version control.

SEE ALSO

Copied to clipboard