Branches, merging and conflicts
A branch is just a label pointing at a commit that moves forward as you commit. Branches let you work on a feature
without touching main. Merging brings the work back. If both sides changed the same lines, git can't
choose, and that's a conflict you resolve by hand.
A branch is a sticky note, not a copy
A ── B ── C ← main
╲
D ── E ← feature/unequip-axe ← HEAD (you are here)
- Making a branch copies nothing. It's a new label on the current commit. That's why it's instant.
HEADmeans "the branch you're on now". When you commit, that label moves forward.mainstays at C, untouched, until you merge.
The commands
| Command | Does |
|---|---|
git branch | List branches (* marks the current one) |
git switch -c feature/unequip-axe | Create a branch here and move onto it |
git switch main | Move to another branch. Your files change to match it |
git merge feature/unequip-axe | Bring that branch's commits into the one you're on |
git branch -d feature/unequip-axe | Delete the label after merging (the commits stay) |
git stash / git stash pop | Put uncommitted changes aside to switch branches, then bring them back |
Older tutorials use git checkout -b / git checkout main. Same thing. switch is the newer,
clearer command.
Team naming: feature/…, fix/…, often with your name or a ticket number:
guy/fix-weapon-map-uproperty.
Two kinds of merge
Fast-forward: nothing to combine
A ── B ── C ── D ── E ← main, after merging (main just slides forward)
If main hasn't moved since you branched, git just moves the main label forward to E. No new commit.
Merge commit: both sides moved
A ── B ── C ── F ────── M ← main
╲ ╱
D ── E ────┘ (M has two parents)
Someone added F to main meanwhile. Git combines both into a new merge commit M with two parents. Usually automatic, unless both sides edited the same lines.
Conflicts
<<<<<<< HEAD
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Combat")
=======
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
>>>>>>> feature/unequip-axe
- Top half (
HEAD) is your current branch's version; bottom is the incoming branch's. - Edit the file to what it should be, which may be one side, the other, or a mix, and delete all three marker lines.
git addthe file to mark it resolved, thengit committo finish the merge.- Panicking?
git merge --abortputs everything back as it was before the merge.
Compile and test after resolving. Git only checks that the text is combined, not that the code still makes sense. Two changes can merge cleanly and still break each other.
Binary files (.uasset) can't be merged at all. Git can't combine two edited Blueprints line by line, so you
must choose one whole file. That's why Unreal teams lock assets (Git in Unreal teams).
Rebase (recognise it, use carefully)
git rebase main replays your branch's commits on top of the latest main, instead of a merge
commit. The history is a straight line, but it rewrites your commits (new hashes). Rule: rebase only commits that are
only yours. Never rebase a branch others have pulled.
Quiz yourself
What is a branch, physically?
A movable label pointing at a commit. Creating one copies nothing.
What is HEAD?
The branch (and commit) you currently have checked out. New commits move that branch forward.
Fast-forward merge vs merge commit?
Fast-forward: the target hasn't moved, so its label just slides forward, no new commit. Merge commit: both sides moved, so a new commit with two parents combines them.
What do the three conflict markers mean, and how do you finish resolving?
<<<<<<< HEAD your side, ======= divider, >>>>>>> branch their side. Edit to the right result, delete the markers, git add, git commit.
A merge had no conflicts. Is the code fine?
Not necessarily. Git only combined text. Compile and test, because changes can merge cleanly and still clash logically.
How do you back out of a merge halfway through?
git merge --abort.
Why can't two people's edits to the same .uasset be merged?
It's a binary file. Git can't combine it line by line, so one whole version must win. Hence asset locking.
What's the golden rule of rebase?
Only rebase commits nobody else has. It rewrites them with new hashes.