Merging on a Team
directions, the release rule, the revert traps, and the verify discipline
$ git log --oneline --graph -4
* 8e35098 Merge branch 'main' into feature-cart
|\
| * 5b529d9 ship auth v2 on main
* | a752b26 start the cart module
|/
* e0410a3 open the appMerges have directions - team labels, not git commands. A back-merge pulls main's progress INTO your feature branch, so you integrate against fresh ground instead of a month-old base. A forward-merge delivers the finished feature INTO main - with --no-ff when the team wants a visible two-parent record of the delivery.
read it: * a save | the other lane |\ lanes split |/ lanes meetThe two directions draw one shape: main's work flows down into the feature, the feature's finished work flows up into main, and both histories stay visible behind the knots:
$ git switch -c cutout release/1.x
$ git merge main
CONFLICT (content): ... config.txt
$ git add config.txt
$ git commit
$ git switch release/1.x
$ git merge cutout
Fast-forwardThe release rule: a release branch should never hold a half-resolved merge conflict - you ship from it. Cut a temporary integration branch FROM the release (the cutout), merge main into it, resolve and COMMIT there, verify - and if the release branch has not moved meanwhile, it simply fast-forwards to the finished merge.
$ git merge feature-login
Already up to date.
$ git revert 71e862a
[main 31b0b03] Reapply "merge the
login feature"Two revert traps every team hits once. First: a revert travels - revert a change on your branch and later merges deliver the cancellation to the target too; the branch looking clean does not unhappen the history. Second: revert a MERGE and the graph still remembers the branch as merged - re-merging brings nothing back ("Already up to date."). The escape is to revert the revert, then merge new work normally.
$ git diff main~1...HEAD -- bake.txt
...
-bake_minutes=40
+bake_minutes=20
...
$ git merge f4-thick # rerere enabled + ruled before
Resolved 'menu.txt' using previous
resolution. # wrappedLast discipline: a clean merge is not a correct merge Before pushing a merge that matters: diff the result against EACH parent (HEAD^1 and HEAD^2 - the seat shows the first), read what it took from each side, and run the tests. On long-lived branches, rerere replays rulings you have made before (until its cache expires).