Git bisect was an extremely powerful tool when I worked in a big-ball-of-mud codebase that had no test coverage and terrible abstractions which made it impossible to write meaningful tests in the first place. In that codebase it was far easier to find a bug by finding the commit it was introduced in - simply because it was impossible to reason through the codebase otherwise.
In any high quality codebase I’ve worked in, git bisect has been totally unnecessary. It doesn’t matter which commit the bug was introduced in when it’s simple to test the components of your code in isolation and you have useful observability to instruct you on where to look and what use inputs to test with.
This has been my experience working on backend web services - YMMV wildly in different domains.
Git bisect is never unnecessary. Even when you can easily test the components and find the bug that way, a bisect allows you to understand why the bug was introduced. This is wonderful in all places where there is a culture of writing long and comprehensive commit messages. You get to understand why the bug occurred from a previous commit message and you will write about that context in your bug fix commit message. And this becomes positive reinforcement. The better the commit messages are, the more useful it is to use git bisect or git blame to find the relevant commit messages.
Yeah, bisect is really handy because often a bug will have been introduced as a side-effect of a change made to support something else, and if you don't know what new usage was introduced you're relatively likely to break that in the course of fixing the bug.
You can avoid it via the "just look at every usage of this function and hold the entire codebase in your head" method, of course, but looking at the commit seems a bit simpler.
‘git blame’ is often more handy for finding the reason that the change was made, assuming you know the location of the bug. It tells you the commit and the commit message.
Automated code formatting, in my experience, never decreases diff sizes, and frequently increases them. Some of those diff size increases support git-blame, some of them hinder it. Around the boundary between two possible formattings, they’re terrible.
Code formatters do tend to force some patterns that may make the line-oriented git-blame more useful such as splitting function calls into many lines, with a single argument on each line; yet that’s not about the code formatter, just the convention. (And the automatic formatters choose it because they have no taste, which is necessary to make other styles consistently good. If you have taste, you can do better than that style, sometimes far better.)
Depends on the language and the available formatters really, I find the black/ruff formatting style in Python to be very consistent, which helps with git blame. For C++ there's no good default formatter for "small diffs" since they all, as you say, add random line breaks dependending on position of parameters and such.
With style you can do better, but having style is impossible in anything except single developer projects.
There are certainly other use cases. git bisect was enormously useful when it was introduced in order to find Linux kernel regressions. In these cases you might not even be able to have tests (eg. a driver needs to be tested against real hardware - hardware that the developer that introduced the bug could not have), and as an user you don't have a clue about the code. Before git bisect, you had to report the bug and hope that some dev would help you via email, perhaps by providing some patch with print debug statements to gather information. With git bisect, all of sudden a normal user was able to bisect the kernel by himself and point to the concrete commit (and dev) that broke things. That, plus a fine-grained commit history, entirely changed how to find and fix bugs.
> With git bisect, all of sudden a normal user was able to bisect the kernel by himself and point to the concrete commit (and dev) that broke things.
Huh. Thanks for pointing that out. I definitely would never have thought about the use case of "Only the end user has specific hardware which can pinpoint the bug."
If all you care about it fixing the bug, this is probably often true. Certainly bisect is not part of my daily workflow. Sometimes though you also need to know how long a bug has been in place e.x. to track down which records may have been incorrectly processed.
Edit: tracking down where something was introduced can also be extremely helpful for "is this a bug or a feature" type investigations, of which I have done many. Blame is generally the first tool for this, but over the course of years the blame and get obscured.
I got to hear about a particularly irate customer during a formative time of my life and decided that understanding why weird bugs got in the code was necessary to prevent regressions that harm customer trust in the company. We took too long to fix a bug and we reintroduced it within a month. Because the fix broke another feature and someone tried to put it back
Example use #1: Customer using a 6-year-old version of the software wants to know if upgrading to a 4-year-old version of the software will solve their problem.
Example use #2: The part of code that was likely previously causing the problem has been significantly reworked; was the bugfix intentional or accidental? If the latter, is the rework prone to similar bugs?
I once bisected to find a bug in a 6 month old commit. An off-by-one error in some array processing. I fixed the bug there to confirm. But on main, the relevant code didn’t even exist any more. It had been completely refactored away.
I ended up rebasing the entire 6 months worth of commits onto the bugfix, propagating the fix throughout the refactoring.
Then a diff against main showed 3 lines changed in seemingly unrelated parts of the code, together triggering the bug. I would never have found them without bisect and rebase.
It sounds like the author doesn't understand the codebase, if you're brute-forcing bug detection by bisecting commit versions to figure out where the issue is, something's already failed. In most cases you should have logs/traces/whatever that give you the info you need to figure out exactly where the problem is.
I found a bug in a OSS program where an entry contained a gibberish string. This was C so apparently it was some not-properly initialized variable. I couldn’t hope to trace down where that occurred. But with time to write a bisect script and half an hour to run the bisect session I was able to find the commit.
In any high quality codebase I’ve worked in, git bisect has been totally unnecessary. It doesn’t matter which commit the bug was introduced in when it’s simple to test the components of your code in isolation and you have useful observability to instruct you on where to look and what use inputs to test with.
This has been my experience working on backend web services - YMMV wildly in different domains.