Originally published at
www.ikriv.com. Please leave any
comments there.
The default git merge is usually all you need, but if you have to deep deeper, you’ll find that git merge command has very weird looking and confusing options.
I created
https://github.com/ikriv/merges repository that shows the result of applying different variants of git merge command.
For starters, git merge -s ours xyz is not the same as git merge -X ours xyz. The first uses merge strategy called “ours”, and the second uses default ‘recursive’ merge strategy, but with “ours” option. Creating two entities named “ours” that do similar, but subtly different things is the epitome of bad interface design.
The “-s” variant creates a commit that merges current branch and “xyz”, but ignores all changes from xyz, so the resulting content would be identical to the current branch. This is useful for getting rid of unwanted branches when force-pushes and deletes are disabled. The “-X” variant only ignores changes from xyz that cause a conflict. Changes from xyz that do not cause a conflict will be included in the end result.
Similarly, git has git merge -X theirs xyz, which will merge current branch and xyz, but will ignore changes from the current branch that cause a conflict and will takes those from xyz instead.
Git annoyingly lacks git merge -s theirs xyz, which would merge current branch with xyz and make the result identical to xyz. This would be very useful to simulate force pushes, but alas. I naively tried to use git merge -X theirs xyz instead and got into hot water.
“Theirs” merge strategy that ignores the current branch can be simulated by creating a temporary branch and using “ours” strategy on it, but why do we need to jump through those hoops?