The bug is alive, and you don't know when it appeared. Or worse: you know it's been there for weeks, but no one remembers what changed. You scroll through 200 commits manually, waste an hour, then discover it was an extra comma in a file you haven't touched in three months. It happens. It happened to us. That's why two tools every developer should know exist: git bisect and git blame. No magic powers needed — just two commands and a bit of method. In this guide, we'll show you how to use them to stop wasting time on bugs you could fix in minutes.
What Is Git Blame and How Does It Help Find the Last Modification on a Code Line?
Git blame is your personal detective. It tells you, for each line of a file, who last modified it, in which commit, and when. It doesn't tell you why the bug was introduced, but it gives you the exact starting point. If the bug is on a specific line, blame shows you the author and the commit that last touched that line. Careful: the guilty commit isn't always the last modifier. Sometimes a bug comes from an earlier change that broke a dependency. But in most cases, if the bug is localized to a line, blame is the fastest route.
Sponsored Protocol
How to Use Git Blame in Practice
# Shows for each line of index.php the author and commit
git blame index.php
# Typical output:
# a1b2c3d4 (Mario Rossi 2024-03-15 10:30:00 +0100 42) $price = $cost * $margin;
# e5f6g7h8 (Luigi Bianchi 2024-03-14 09:15:00 +0100 43) $tax = $price * 0.22;
The code above shows: commit hash (abbreviated), author, date, and line number. If there's a calculation error on that line, you know who touched that point and when. But beware: if the bug was introduced by a line that hasn't been modified since, blame will point to an even older commit. If no one ever modified that line? Then the bug has been there since the file was created. Blame still gives you the creation commit.
Limitations of Git Blame
Blame works when you know exactly which line the bug is on. But what if the bug is a behavior that can't be traced to a single line? Or if the bug only appears under certain conditions, like a logic error in a function? In those cases, blame isn't enough. You need git bisect.
What Is Git Bisect and How Does Binary Search on Commits Work?
Git bisect implements a binary search over the commit history. Instead of testing each commit one by one, it splits the suspicious interval in half and asks you: "In this commit, does the bug exist?" Each answer halves the number of commits to check. With 100 commits, it takes about 7 steps. With 1000, about 10. Much faster than linear search.
Sponsored Protocol
When to Use Git Bisect
When the bug is reproducible and you don't know when it appeared. Classic example: a checkout form stops working. You know it worked a week ago. Today it doesn't. You don't remember what you changed. With bisect, you tell it: "The commit from a week ago was good, today's is bad." It guides you through the intermediate commits, asks you to test them, and finally tells you exactly which commit broke everything.
How to Run Git Bisect Step by Step?
1. Start the Bisect Session
# Suppose the bug is in the current commit HEAD (bad)
# and the good commit is identified by tag v1.0
git bisect start
git bisect bad # mark current commit as bad (contains the bug)
git bisect good v1.0 # mark v1.0 as good (bug free)
Git checks out a commit halfway between the two extremes. Now you need to test that commit.
Sponsored Protocol
2. Test the Current Commit and Mark Its State
# After manually verifying or using an automated script:
# if the bug is present in this commit:
git bisect bad
# if the bug is not present:
git bisect good
# Git automatically moves to the next commit to test.
# Repeat until Git shows you the guilty commit.
At the end Git prints something like:
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0 is the first bad commit
You can see what changed in that commit with:
git show a1b2c3d4
3. Automate with a Test Script
If you have an automated test that reproduces the bug, you can pass it to bisect with the run option:
git bisect start HEAD v1.0
git bisect run phpunit tests/CheckoutTest.php
The command runs the test on each commit. If the test fails (exit code non-zero), bisect marks it as bad. If it passes, as good. At the end it gives you the guilty commit. Saves hours of manual work.
4. End the Session
git bisect reset
Restores the repository to its original state. Don't forget this step, or you'll stay in bisect mode.
Sponsored Protocol
Git Blame vs Git Bisect — Which Tool to Use in Which Situation?
Blame is for bugs localized to a specific line. Bisect is for diffuse bugs, unexpected behaviors, regressions. If you don't even know which file to look in, bisect is the right choice. If you know the line but not the commit, blame gives you the answer in one command. Often they're used together: first bisect to find the commit, then blame to understand exactly what changed in that commit on a specific file.
Git Bisect and Blame in a Team — How to Avoid Conflicts and Misunderstandings?
In a team, blame can create tension if used poorly. "Who wrote this crap?" is the wrong approach. We use it with a rule: blame is for understanding context, not for blaming. A bug might have been introduced by a change that seemed harmless in a different context. Bisect is purely technical — no judgment, just search. We often integrate it into our CI workflows to automatically run bisect on regressions reported by tests. That way the developer receives the guilty commit directly and can fix it without wasting time searching.
Sponsored Protocol
What to Do Now to Start Using Git Bisect and Blame?
- Try blame on a file you know: open your terminal in your repo, type
git blame filenameand observe the output. Identify a line and verify the corresponding commit withgit show. - Simulate a bug to practice bisect: create a test repository, make several commits, then deliberately introduce a bug in an intermediate commit. Use bisect to find it. Do it manually first, then automate with a script.
- Integrate bisect into your debugging flow: next time you have a regression, instead of random searching, start immediately with
git bisect start. Time how much you save. - Always reset: after each bisect session, run
git bisect resetto return to normal state.
We, at Meteora Web, use these tools daily in our Laravel and WordPress projects. When a client reports an anomaly, we don't start looking at code randomly. We run bisect, find the commit, and fix it in minutes. If you want to dive deeper into version control and team workflows, check out our main article: Git for Developers — From Basics to Team Workflows for Conflict-Free Code.