23

When working on a fix or a feature, I sometimes stumble over other tiny issues that can be improved on the fly in a matter of seconds. When I do them immediatly and then commit the finished feature/fix, the commit includes more than one thing. For example "add feature X and code clean up" or "fix bug X and improved logging". It would be better to split this into two commits. In case the two changes happened in the same file, I can not simply add one file, commit, add the other and then commit again. So I see the following three options:

  1. Deliberately overlook non-related things while working on something.

  2. Copy the file with two changes, revert it, include one change, commit, include the other change, commit again.

  3. Do not change small unrelated things but add them to a todo list and do them later.

I do not really like all of the three options, because of the following reasons:

  1. Code quality can suffer if one does not fix small problems. And I feel bad if I consciously miss a chance to improve something without much effort.

  2. This increases manual work and is error prone.

  3. This is fine for not-so-tiny todos, but adding a tiny item to a todo list and revisiting it later often takes much longer than just fixing it immediatly.

How do you handle such situations?

Tobias Hermann
  • 608
  • 5
  • 15

6 Answers6

12

I think that you have to be very pragmatic when programming. Even if it might be possible to formulate the perfect scheme, workflow, or implementation, sometimes you just need to get work done. Here's what I do:

I use git's ability to stage/commit individual hunks and lines, whenever possible, to separate unrelated changes, although, occasionally this can introduce temporary problems, if the separation was not done properly. Since the changes will be adjacent, it's usually not a massive problem, unless you have a policy of testing every individual change in your CI pipeline.

When the unrelated change is too large, I will put it on a todo list, and usually take it on right after, while its fresh in my mind. Sometimes it might take a day or two before I can get back to it, it depends on my current task and train of thought. Occasionally I will simply put a TODO: next to the offending code, if I don't have a good solution ready.

It happens that it's just not practical to separate things and I will commit the minor adjustment along with the original work.

The size of the change is usually the determining factor when I pick the route to go, but in the end I would much rather ignore a workflow rule, than leave a smell behind.

axl
  • 1,267
7

My editor has a plugin that makes staging individual parts of a file extremely easy. I imagine other programmer editors might have similar plugins, although you can always do it the manual way with git add --patch | -p. Then I use git stash to save off my other changes to test my small commit in isolation. Then after I commit, I just do a git stash pop and continue where I left off. That's precisely what those features were designed for.

Karl Bielefeldt
  • 148,830
2

The trick is not to make changes unless you are prepared to put as much effort in as the change deserves.

What I do tend to do is add to a todo list (sometimes by adding comment to the code, sometimes in a note on a bug ticket, and sometimes by updating the code in a separate branch knowing the fix will get merged in eventually). If there is no bug ticket for a rollup of minor quality issues, I raise one specifically for this, so I and everyone else can tell what the reason for those code changes was when the branch gets merged. I never just make changes for the fun of it, everything gets traceability so my colleagues will not be too surprised when code changes.

So in short - yes, overlook them when coding. If you're adding a feature, do not be tempted to add 2 features, no matter how small. If someone decides to revert your branch (because your feature is no longer required, say) then you will also lose all your mini-bugfixes. Similarly, you do not want to make a small 'fix' in some critical code that was working correctly.

gbjbaanb
  • 48,749
  • 7
  • 106
  • 173
2

An option I use quite a bit is to add TODO comments, then do lots of frequent "partial" commits, by using git add --patch to select the relevant parts of the file. Then use git rebase --interactive to reorder and merge the partial commits into the final feature and fixup commits before pushing them.

This keeps your main commit clean, and still allows you to fix other issues you find immediately.

There's nothing wrong with a git rebase in this context as you're only rewriting local commits.

Tom
  • 309
1

Another option could be to "git stash" your current changes. The workflow would look like this:

  1. Start making changes related to Feature A
  2. Discover Bug B and decide to fix it immediately
  3. From the command line in your repo perform git stash (After which your code will be back to the state it was in before you started working on Feature A)
  4. At this point your uncommitted changes for Feature A are stored in the "stash"
  5. Make the code changes necessary to fix Bug B and make a commit back into the repo
  6. From the command line run git stash pop
  7. Your uncommitted changes for Feature A are now popped off the stash and restored to your in progress code along side the (already committed) fix for Bug B
Zach
  • 131
0

Separately stage (and commit) the changes related to the bug-fix. In Git Extensions, this is extremely easy to do. From the commandline, I think you need to do git add -p.