Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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?

like image 792
LiKao Avatar asked Nov 23 '11 15:11

LiKao


People also ask

What happens if you get a conflict during a merge?

Merge conflicts happen when you merge branches that have competing commits, and Git needs your help to decide which changes to incorporate in the final merge. Git can often resolve differences between branches and merge them automatically.

Can I stash a merge in progress?

The in-progress merge is stored in the index and work-tree. Given that git stash makes two commits out of these two, you would think it would be just the right thing—except that the in-progress merge state cannot be stored in a commit: it contains metadata that git will not write into a tree.

How do I fix stash pop merge conflict?

The stash entry is kept in case you need it again. There's no magic remedy for such merge conflicts. The only option for developers is to edit the file by hand and keep what they want and dispose of what they don't want. Once they merge and save the file, they will have effectively resolved the git stash conflict.

Should I commit before merging?

If there were uncommitted worktree changes present when the merge started, git merge --abort will in some cases be unable to reconstruct these changes. It is therefore recommended to always commit or stash your changes before running git merge.


1 Answers

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!

like image 99
Cascabel Avatar answered Sep 28 '22 02:09

Cascabel