Stashing while merging
I have a problem that has just come up with a colleague of mine and I am wondering about the best git workflow for this problem.
Let’s say we have two branches A and B. Now we change some file (
foo.c) both in A and B, so we get a merge conflict when we are merging B into A. Now let’s say some developer messed up and left the branch A in a broken state, and the error is also in foo.c, but in a line which was not merged.
I see some possibilities to handle this situation:
Stash the pending merge, fix the problem on A, commit and then apply the merge again. However at this point I am not sure how to handle the correct merge strategy for the changes that both have been doing to foo.c. The broken part might affect some of the stuff I have done, and so I do not see a clear way of resolving the conflicts.
Undo the merge, fix the problem on A and then redo the whole merge. However I might have already resolved other conflicts, so this might loose a lot of work.
Take the –theirs/–ours version of the file, go through with the merge, fix the changes, cherry pick the changes which have been lost. However then I will have some changes twice.
Some other solution, that I cannot think of.
All these solutions strike me as a bit unsatisfactory. From my usual experience I would probably go with 1, but i am absolutely unsure about this.
How would you handle such a situation?
One Solution collect form web for “Stashing while merging”
You can’t stash away an uncommitted merge. Option 1 is off the list immediately.
In terms of clean history, a variation on option 2 is best. Git has the ability to remember conflict resolutions; it’s just disabled by default. You can enable it:
git config --global rerere.enabled. Resolve conflicts as desired. Normally you’d then commit the merge, and Git would record the way you resolved the conflicts. Since you don’t actually want to commit the merge yet, you can just run
git rerere to immediately record conflict resolutions without committing. (Alternatively, if you went ahead and committed the merge, you could just
git reset --hard HEAD^, resetting to before it. The conflict resolution would still be remembered.)
You can then fix the issue in branch A, and redo the merge. Git will reuse the recorded conflict resolution. It will still be marked as unmerged, so that you have a chance to review it and make sure it did the right thing, before running
git add on unmerged paths, and committing the merge.
And I’m unclear on option 3, actually. Why would you have to cherry-pick? It sounds like
foo.c is broken only in branch A, which is the one you’re merging into, so all this would be within branch A. The desired history is bugfix followed by merge; if you instead go ahead and merge then fix the problem, you’re just switching the order of two commits. In any case, it shouldn’t be necessary to have duplicate commits – I can help avoid that if you clarify!