This has happened to me more than once, so I've been thinking about how to organise my branching and merging to allow for this scenario.
- I get my ticket to do some new feature on the application I'm working on.
- I create a feature branch, usually in the format of feature/(ticketNumber)-(title) (Yeah, we follow A successful Git branching model)
- I think to myself "I've got some time to get this done, I'll take the opportunity to refactor this code so it's nicer, in the process of getting this new feature done" (Insert "Upgrade library/framework" here as well).
- So I start refactoring, and continue on working on my new feature…
- Until I get a: "Hey Mark, we have changing priorities/emergency/we have a better idea/never-mind, so backburner/kill/delay/switch to working on this totally new thing over here".
- So I go off and start a whole new feature, and get that done instead.
- Later on, I come to do something else in the area I was working in previously, and realise the refactoring work I was doing previously would be super useful. However all of it is tied in with other half finished code in my previous feature branch. That sucks, because it would make what I'm working on a million times easier.
I call it the "Lost Refactor", and it drives me nuts, as you know you could be working on better code, but it's all attached to other code that you would have to manually pull apart.
So what do you do? I have two thoughts on the matter:
- Separate the refactoring into a separate ticket, and build a separate feature branch for it.
- Create a refactor/(ticketNumber)-(title) branch, specifically for the refactoring work, and merge that into my feature branch.
- Make sure my commits are clean enough so that I can cherry pick out which ones are pure refactor, and which ones are the partial implementations of the new feature.
I've yet to try out option #2, but it seems to me that that would be the best approach.
Technically you could claim that the refactoring would be a totally separate ticket – but that seems like more trouble than it's worth from a pragmatic standpoint. However, the refactoring is a separate effort than the ticket, which means it's nice to split off to it's own branch, in case you want to integrate that work separately. Having the
refactor/ branch be the same as the
feature/ branch name, it also gives you a really good idea of what the original impetus for the refactoring came from.
Option #3 is not a bad one – and probably the easiest from the development workflow (not having to switch branches around), but the idea of cherry picking commits makes me shudder a bit. I guess it depends how often you end up in a "lost refactor" type scenario, that if it was rare enough, doing the occasional cherry pick is not the end of the world.
What does everyone else do? Do you find yourself in this situation often? What approach do you take?