Our shop has a fairly rapid deploy cycle (1-2 weeks between when the code is written and when it's released). As such, after a bit of experimentation we've adopted the following pattern for our Git usage:
- Developer creates a branch, based off master, for their specific ticket (ie. "bug-5555" branch)
- Developer commits the code for the fix to that branch
- A supervisor rebases our "pre-master" branch (a copy of master with the current release candidates on top of it) in to the bug branch
- A supervisor merges (fast-forward-style) the commits from the bug branch in to the pre-master branch
- The QA team qa's the fixes in the pre-master branch
- If a fix fails QA, it is rebased out of the pre-master branch
- (After a fix for the QA failure is completed, steps 3-5 are repeated)
- When we're ready to release, the pre-master branch becomes the new master branch
This style has a number of advantages for us: it makes it so the QA team is testing exactly what is going to go live, it makes it easy for us to put stuff in and take stuff out of QA, it keeps the code for a specific fix all nice and tidy in its own branch, etc.
However, several people here are concerned about our use of rebase (both to rebase the current pre-master in to the fix branch before merging that fix branch in to pre-master, and to rebase the pre-master branch to take out failed fixes). Their concern is that rebasing could potentially result in lost history, and as such we should rebase as infrequently as possible.
However, without rebasing the only alternative we've come up with is to make the pre-master branch a dead-end branch, used only for QA. This would make rebasing that branch safer, and when we're ready to release we'd re-merge the fix branches directly in to master. The problem with this approach though is that QA wouldn't actually be testing what's going live, and an improper merge conflict resolution (when merging the fixes in to master) could easily slip by them (unless they re-qa everything all over again). This is the main reason why we've stuck with our current approach, despite the rebasing concerns.
So, with that very long prelude out of the way, my actual question is ... well it's two-part:
- Which do you think is worse: the risk of not QA-ing exactly what is going live, or the risk of losing history (or actual code) from the (limited) amount of rebasing we do?
- Does anyone see a third option to what I've outlined, which would give us the same flexibility and testing of what's actually going to go live, without the dangers of rebasing?