How to prevent many git conflicts when rebasing many commits?
Fortunately, git has a mechanism for dealing with exactly this problem called git rerere
- essentially, if you have git rerere
enabled, then each time your resolve a conflict the fact that you resolved that exact conflict in a particular way is remembered. If the same conflict comes up again, the same resolution is automatically used. There are some helpful articles below:
- http://scottchacon.com/2010/03/08/rerere.html (blog post)
- http://git-scm.com/docs/git-rerere.html (manual entry)
- Are there any downsides to enabling git rerere? (question in stackoverflow)
- http://progit.org/2010/03/08/rerere.html (original answer link: seems broken)
... but essentially you can just do:
git config --global rerere.enabled 1
... and forget about it, while enjoying easier rebasing / merging :)
Make sure that you are always rebasing using the --onto
switch.
To prevent conflicts, use floating development branches. Each developer will continuously rebase their development branch. This is easy since the developer knows what he just implemented and shouldn't have problem with solving conflicts. Instead of rebasing, just merge the final version (it will already be rebased).
You can squash her branch to prevent Successive conflict resolving. when you squash all commit in her branch after creating from master into one commit, then conflict can be resolve in one step.
If you want to write the new commit message from scratch, this suffices:
git reset --soft HEAD~3 &&
git commit
In this example, we'll squash the last 3 commits.
To prevent this problem in the future, I recommend you to rebase your branch with source branch after each commit.
Let me share one possible way to resolve rebase conflicts. I call it rebase via merge. It can help if you want to rebase a branch with many commits and many conflicts are expected.
First, let's create a temp
branch and force all conflicts to show up with a regular merge
git checkout -b temp
git merge origin/master
Resolve all the conflicts the regular way and finish the merge.
So temp
branch now shows how the project should look like with all the conflicts resolved correctly.
Now let's checkout your untouched branch back (let it be alpha
).
git checkout alpha
And do a rebase with mechanical conflict auto-resolution in favor of current branch.
git rebase origin/master -X theirs
The project code can be broken or invalid at this moment. That's fine, the last step is to restore the project state from temp
branch with a single additional commit
git merge --ff $(git commit-tree temp^{tree} -m "Fix after rebase" -p HEAD)
Basically, this step uses a low-level git command to create a new commit with exact same project state (tree) as in temp
branch. And that new commit is being merged immediately.
That's it. We just did a rebase via hidden merge. And temp
branch can be deleted.
git branch -D temp
Also, there is a script to do the same thing interactively. It can be found here.