0

I've seen blog posts explaining how to do Git bisect, but how to you fix the bug, commit again and maintain the rest of the commit history?

An actual problem I faced in my project was like this (the image is just an approximation):

enter image description here

I had marked the top-most commit as bad and the bottom-most commit as good. Some of the commits below Buggy commit A were good commits, because somewhere in-between, I had commented out the code that made Bad commit B a bad commit. So naturally, git bisect led me first to Buggy commit B.

I corrected the bug and when I tried to commit, I wanted the changed lines of code to be applied to the same Buggy commit B commit. But I found out that:

  1. Git would always create a new commit for this
  2. I got the detached head error:

    HEAD detached at b855e36 Changes not staged for commit:
    modified:  main.cpp
    

Now what do I do?

Create a new branch (let's name it fixedit) and commit this corrected code? If I do, then what happens to all the other commits above it? Should I do a rebase (never done it before) of the commit above Buggy commit B and put the entire line of commits onto the new fixedit branch?

I would prefer that I'd just be allowed to modify the existing commit and the entire tree would remain as it is, but then I'd have to go to all the commits above Buggy commit B and fix the buggy line in all those commits. That doesn't make sense. So how does one fix bugs and yet retain commit history properly?

UPDATE:

So I do a git bisect reset and fix the code on the topmost commit (because I know which line of Buggy commit B introduced the bug)?

Like I mentioned earlier, the code that caused Buggy commit B was commented out in one of the commits just before Buggy commit A.

  1. So when in my topmost commit I see that the line is commented out, I realize that the bug is somewhere else.
  2. During the first bisect since one of the commits between A and B was marked good, I'd choose that as the good commit for my second Git bisect attempt, and the topmost newest commit as the bad commit and then continue with Git bisect. That'd lead me to Buggy commit A.
  3. Then I'd do a git bisect reset and correct the lines of code in the topmost code and then commit.

Ok; that makes sense. Thanks :-)

  • meta.stackexchange.com/q/43478/165773 – gnat Jan 16 '16 at 15:14
  • As a side note, git blame is usually more efficient to find the commit if you already know the line of code that caused the bug. git bisect is mostly for when you have a large range of commits that might have caused a bug, and you have no idea where to look in the code. – Karl Bielefeldt Jan 16 '16 at 15:32
  • Hmm...interesting info about git blame. Actually, for bad commits A and B, I didn't know which line of code caused the problem, so bisect was necessary. After finding the commit I had a look at the files that had got modified during the commit and the diff of what changes were done. Looks like that's exactly what a blame does. Still, blame and show seem to be nice ways of getting the job done. Thanks! – Nav Jan 17 '16 at 7:40
  • @gnat: What's with the link on chameleon questions? I didn't change the question. I was mentioning the solution (and mentioning to delnan that I understood what he explained) to the problem, as part of my update to the question. – Nav Jan 17 '16 at 14:36
14

You don't fix that commit. It's a fact that the bug was introduced, and that's okay. You found it now and know how to fix it, great! Like with any other bug fix, you create a new commit on top of the current state of the project. This retains the history and fixes the bug. Rewriting the history so that the bug never existed is pointless, even dangerous:

  • It doesn't have any benefit. I mean, you could pretend the bug never existed, but if you had to bisect then the bug probably existed for a while and was encountered by users. Rewriting git history doesn't undo that. It will just make it harder to understand what happened.
  • If the code at and around the location of the bug fix has changed in other ways since the bug was introduced (which seems to be the case), you can't just fix the bug in commit B and rebase all later commits on that. You would have to manually resolve conflicts, which takes time and risks introducing new bugs.
  • The usual concerns regarding rewriting history apply in force. Rebasing so many publicized commits will cause trouble for everyone who has work based on these commits (e.g. if they have a branch based on a commit after B, they won't be able to merge this branch easily). More generally, it breaks all references to specific commits (that came after B), since all hashes change.
  • Thanks. I've updated my question to explain what I understood. – Nav Jan 16 '16 at 13:56
  • 3
    @Nav: "So how does one go about doing 'create a new commit on top of the current state of the project'." Just commit the fix for the bug. No bisecting or resecting or anythingsecting. Just commit the fix, as you would any other code change. You're massively overthinking this. – Lightness Races in Orbit Jan 16 '16 at 14:07
  • Commit changes after 'git bisect reset' – Basilevs Jan 17 '16 at 15:50
  • I disagree. I just had a good branch with no issues. I rebased on top of branch I wanted to merge to. That made the project not compile. The solution is to rewrite history so that the bug never existed, because it never existed before rewriting the history for the first time. – arekolek Dec 3 '18 at 8:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.