24

This happened at least once to me. I'm working on some part of the code base and find a small bug in a different part, and the bug stops me from completing what I'm currently trying to do. Fixing the bug could be as simple as changing a single statement.

What do you do in that situation?

  1. Fix the bug and commit it together with your current work
  2. Save your current work elsewhere, fix the bug in a separate commit, then continue your work [1]
  3. Continue what you're supposed to do, commit the code (even if it breaks the build fails some tests), then fix the bug (and the build make tests pass) in a separate commit

[1] In practice, this would mean: clone the original repository elsewhere, fix the bug, commit/push the changes, pull the commit to the repository you're working on, merge the changes, and continue your work.

Edit: I changed number three to reflect what I really meant.

7
  • 2
    Why not commit both the bug fix and your change in a single transaction ? It's pretty common, and clean. You have to put proper comments in your commit of course.
    – user2567
    Sep 27, 2010 at 13:39
  • @Pierre, that's number 1. I think I could choose a better word than silently.
    – imgx64
    Sep 27, 2010 at 14:13
  • I usually put multiple fixes in the same commit. I reference them using task ID, and I have even Trac to attach my commits to tasks automatically with a special hook I've installed
    – user2567
    Sep 27, 2010 at 14:30
  • 2
    @Pierre 303 Oh man, such a bad practice! Split your commits to granular. Oct 15, 2010 at 20:16
  • @mathepic: when a change affect only one task yes, but when it affects multiple tasks, it's just not possible without breaking the build
    – user2567
    Oct 15, 2010 at 20:38

11 Answers 11

17

I have done 1 and 2 and in the end, I think I prefer #2. It allows for more visibility for the bug fix, which may be important for QA/release notes/other developers.

I've also come across a situation where what I thought was a bug actually wasn't (not saying that this is the case here), and "fixing" it in a separate commit allowed another dev to contact me and explain what was what instead of the "fix" just getting lost in my normal check-in.

12

I generally go for #2. It makes the repository cleaner, and makes the logs more understandable. I hate it when other devs I work with commit 15 different bug fixes, features, and refactorings all in the same commit.

Also, depending on how your team does defect tracking, you may need to search the defect repo to make sure that if the defect you are fixing is in there, you mark the item complete. Or, you might need to create a new item and mark it complete so that the defect system and the code repo match up.

8

I do #2. Using tools like git makes it trivial to split it up into multiple commits. If you can't convince your team to switch to more modern tools, git-svn will give you a decent portion of what you'd use to solve this problem. This blog post gives a good overview of the workflow that you're trying to solve: The Thing About Git

4
  • Thanks, that blog post is very useful, and applicable in my case (I use Mercurial, which more or less has the same features as git). I think I should read The Book someday.
    – imgx64
    Sep 28, 2010 at 11:40
  • @imgx64: I don't know if it has an equivalent to the index though. It's git's killer feature IMO
    – Daenyth
    Sep 28, 2010 at 16:00
  • Reading the comments in that blog post, Mercurial has equivalent extensions. The shelve extension does what I need.
    – imgx64
    Sep 28, 2010 at 17:38
  • @imgx64 Shelve can be useful, yes. But the Record extension is more appropriate I think. I use it only through the TortoiseHg GUI (you can double-click on a diff to remove/add it to the commit).
    – barjak
    Dec 27, 2010 at 16:10
4

I choose the unwritten option (4): Divide your project into highly-specialized assemblies/libraries, so that unrelated bugs will always be in a different location in the version control tree.

I apologize if the above sounds snarky, but I mean it sincerely. I cringe whenever I see a monolithic project with a hundred forms and namespaces that have nothing at all to do with each other. I used to face this same dilemma often, wondering if and how I should break up commits that were dealing with different functional areas; it wasn't until much later that I realized that having all of these different functional areas in a single committable project was, in itself, a major design flaw.

I still frequently find totally unrelated bugs while I'm working on a specific feature. I might be working on the UI and find a bug in some business logic, and have to fix it before I can move on. The difference is that the business logic is always in a different assembly/project from the UI, so all I have to do is make one very minor change to the BL and proceed with one very minor commit, then keep on working.

Having a really good project organization makes it not only possible, but quite easy to handle these issues without burying a change, breaking the build, or getting mired in an irritating branch/merge (even if you're using a DVCS it's not totally painless).

If you lack this option - i.e. you're a junior dev with no say in the project organization - then I would simply go with #1 and make appropriate notes in the log so other people know why you did what you did. If you've made a major change then also file a bug report in your issue tracking system to give visibility into what you've fixed and why.

2
  • 3
    While I agree, that doesn't work in all situations. The 'bug in a different part of the code' might be in a parent class or even in a different method in the same class. You can't separate those in different libraries.
    – imgx64
    Sep 28, 2010 at 11:47
  • @img: Sure, but if the "different part" of the code base is in such close proximity to what you're working on, then it probably doesn't even justify this much attention - just fix it! :P
    – Aaronaught
    Sep 28, 2010 at 14:41
3

I usually just fix the bug, and then continue what I was working on. When it's time to commit, assuming the bug fix is in a separate file, I do two simultaneous commits -- the first is a partial commit containing only the bug fix, and the second is everything else.

1

I try to do #2. If it really is a separate issue, chances are good that it is in a file that is different than what you are working on. You should be able to check the file in as a separate commit, even if it is made in the same repository you are working on. For all the reasons stated already, it just makes sense to have commits as independent as possible, for tracking and well as reverting the change if it is wrong.

1
  • 3
    With Git, you can split multiple changes in the same file across several commits - I often miss not having this when working on SVN-based projects. Sep 27, 2010 at 17:14
1

Short answer: #2. You really want that bugfix (with its note in your tracker!) tagged in your version history as a separate entity.

Longer answer:

  • Stumble across the bug
  • Write a test or more demonstrating the bug
  • Make the test pass
  • Commit just that change and its tests (git add --interactive or darcs record -i or however your VCS does it) (*)
  • Get back to what I was doing.

(*) In CVS (no, really) I sometimes have a clean tree checked out as well as a copy on which I work. Then I use a merge - winmerge, in my case - to pull just the bugfix into the clean tree so I may commit it separately. (The other option's to rename your changed files, cvs update and merge. When you've committed the change, remove the file and rename your moved files back to their original names.)

Something to note though is that I usually only find bugs that are either related to what I'm working on, or are in close lexical proximity. I would be surprised if it was normal for people to find bugs in unrelated parts of the codebase - why are you reading unrelated code when fixing the bug? (Yes, this is the exact opposite of what Aaronnaught says!)

1

I fix the bug and I do separate commits, one for each fix/feature.

Most of the time, the changes are not in the same file, so it's easy to separate the commits. If the changes are in the same file, I use TortoiseHg (a mecurial GUI front-end) to select precisely the diffs I want to commit (I think it's possible to do this on the command line with the Record extension, but it's less convenient).

Some people use the Mercurial Queues to isolate the minor fixes while working on a feature. The minor fixes are stacked up in the MQ, and when the feature is finished and committed, the content of the queue is also committed (one changeset for each entry in the queue).

0

I usually do #2. Saving my current work elsewhere: this usually works fine by creating a patch. Also some IDEs (IntelliJ) allow for shelving changes which is exactly that: save the current work elsewhere.

0

What I do depends on whether the bug truly is in a different part. If it is, then checking it in is independent of my half done changes. I make the change, build that different part to be sure I haven't made some trivial error, test it (perhaps by doing whatever it was keeping me from doing) and check it in explaining what was happening. Often I will make a work item for it, and after the checkin/resolve, assign the WI to a tester. Then I go back to what I was doing.

If it's all mushed up with the files I have half changed, I can't build and test that part independently. In that case, I make another WI for it and when I check in my changes I resolve both WIs with the same checkin, which usually is against my principles, but applies well in this case.

In both circumstances the bugfix ends up tested by me, checked in with some sort of trail so people understand why I randomly changed that code that day, and a WI is assigned to someone else to confirm it's correct now.

0

We do #1. #2 sounds good, but i can't say we've had problems with #1 that #2 would fix.

An additional factor in my company is that we build web apps, and our testing is almost entirely through the web interface - roughly, what people call functional testing rather than unit testing. We have all tests pass before checking in. Splitting commits into smaller bits would mean running the tests once for each bit, and that would take up more time. I would love to have a much faster test suite, which would let us do smaller commits, but we just don't have it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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