Branching, Merging and Conflicts
Branches are cheap pointers; merging combines histories with a three-way merge from the best common ancestor. Know when Git fast-forwards, how strategies differ from strategy options, and how to resolve each kind of conflict.
Key points
- 1
A branch is a ref holding one commit hash; HEAD normally points at the current branch. Creating or deleting a branch copies or deletes no files.
- 2
A merge fast-forwards when HEAD is an ancestor of the merged commit.
--no-ffforces a merge commit;--ff-onlyrefuses anything but a fast-forward;merge.ffsets the default. - 3
ort (default since Git 2.34) does a three-way merge against the merge base; with several bases it builds a virtual ancestor.
- 4
-s ourskeeps your tree exactly and records the other branch as merged.-X ours/-X theirsonly pick a side for conflicting hunks. There is no-s theirs. - 5
--squashstages the combined changes with no merge parent, sobranch -drefuses and later merges of the same branch can re-conflict. - 6
During a merge, "ours" is HEAD and "theirs" is the merged branch. During a rebase they swap: "ours" is the branch you are rebasing onto.
- 7
Resolve conflicts,
git addeach path, thengit merge --continue. Setmerge.conflictStyle = zdiff3to see the base, and enable rerere to reuse resolutions.
Common traps
Treating
-X oursand-s oursas the same: one breaks ties, the other throws away the whole other side.Expecting
git checkout --oursto mean "my branch" during a rebase.Assuming a clean merge means working code: semantic conflicts merge without markers, so build and test the merge result.
Test yourself on Branching, Merging and Conflicts
Ten questions, with the answer and explanation after each one.