I've been working the past two weeks in a feature, and I created a separate branch for it. The problem that the task took me long and I didn't rebase to master periodically. I ended up with 100+ commits and now when I'm trying to rebase the branch to master using
git rebase master
git rebase --continue
This depends in part how you've done your 100+ commits and what's been happening in the mean time. Four strategies might be useful:
If you have a beautiful clear stream of 100 commits that never modify the same code twice, I'm sorry, but you are stuck.
However, from 100 commits in two weeks, I'm guessing your commit history does not like that. Perhaps you've modified function X 5 times within the commit history, and each one of those commits is going to cause a conflict. If only you had one single commit that modified function X, you'd have 20% of the work to do.
So the answer here is to tidy up your commit history before you rebase onto master. This is another use for 'git rebase'. Rebase it onto its existing base, but use
git rebase -i to interactively squash together and reorder the commits. Make sure you have the minimum number of commits and that each of those does something independent. You can take the opportunity to change your commit logs too. Key backup branches (
git branch) and
git diff to those after each commit to check you've not changed anything.
In particular, if you have internal merge commits, flattening these is helpful.
Inevitably when I do this I find stuff I did wrong, or could have done better, even if it's 'only' code formatting or commit messages. You can take the opportunity to fix these. I'm guessing you should be down to 10 or 20 commits when this is done - far more manageable.
If you've already done that, you are probably going to have to bite the bullet. However, if a colleague has been refactoring whilst you've been working, sometimes what you are best doing is as follows. Imagine the tree looks a bit like this:
A --- B --- C --- D --- E --- F -- .... -- X --- Y --- Z (master) \ \----- 1 --- 2 --- 3 --- 4 .... 97 --- 98 --- 99 --- 100 (you)
What you want to do ultimately is to rebase onto Z. However, this gives you loads of conflicts. Let's suppose commits D and E are two megacommits from a colleague refactoring something your code is dealing with. Sometimes, it's easier to:
Sometimes things have got really complicated on the tree you are trying to merge into. A classic case is that (using the above diagram), commit G reverts commit C, then commit H redoes (or almost redoes) it, and in the mean time there are merges (particularly of things you've might have merged in too). Thanks colleague, that's made rebasing really simple. Other things that cause difficulties are complex merge commits and nasty renames. Each commit tends to give you the same conflicts again and again for no apparent reason.
git rebase Aarrggh.
One technique here is to flatten a copy of the master tree, i.e. branch master (locally), then rebase it squashing the whole thing into a single commit from A to Z. You can flatten your stuff a little first too (see above). Then rebase onto the flattened master. Now you've got the 'right' set of commits, you can easily rebase that onto master (well, onto 'Z' as master may change) because the code's exactly the same.
git rebase seems to go into a fugue state of conflicts, and it's time to break out
git format-patch and
git am to reapply it in whole or in bits. This is really useful if someone has renamed a file (as you can fix the filename in the patch in your editor) or renamed a common class/variable/whatever (as you can find/replace in the patch).
Next time, rebase onto master more frequently. It's less painful if you do it as you go along.
Also, if you have two people working on the same area of code and it produces a pile of conflicts, perhaps your code's not well abstracted enough, or perhaps you are working on top of each other and could divide up your work better?