Learning Objectives
By the end of this lesson you will be able to:
- Describe the three commits Git compares during a merge
- Apply the direction rule and merge into the correct branch every time
- Predict whether a merge will succeed cleanly before running it
- Read the summary Git prints after a merge
The Direction Rule
Before any mechanics, the rule that prevents the most common merge mistake:
You merge a branch into the branch you are standing on.
git switch main # stand on the destination
git merge feature/auth-test # bring the source in
main changes. feature/auth-test does not change at all. If you run these two commands the other way around, you will bring main's work into your feature branch — which is sometimes exactly what you want (Lesson 2.3) but is rarely what you meant when you were trying to release something.
Check before you merge. Every time:
git branch --show-current
The Three Commits
A merge is a comparison between three points in history, not two.
A───B───C───D ← main
\
E───F ← feature/auth-test
- The merge base — commit
B, the most recent commit both branches share. Git finds this automatically. - The destination tip — commit
D, wheremaincurrently points. - The source tip — commit
F, wherefeature/auth-testcurrently points.
Git then asks two questions:
- What changed between
BandD? (Whatmaindid since the split.) - What changed between
BandF? (What the feature branch did since the split.)
And it combines both sets of changes into one result. Where the two sets touch different files, or different regions of the same file, Git applies both without asking. Where they touch the same lines, it stops and asks you — that is a conflict, and Module 3 is entirely about it.
This is why "merging is dangerous" is a myth. Git never guesses. It either combines changes it is certain about, or it stops and hands you the decision.
Running It
git switch main
git merge feature/auth-test
Updating 8f3c2a1..d4e5f6a
Fast-forward
tests/auth/expired-token.spec.js | 42 ++++++++++++++++++++++++
config/test-env.yaml | 3 ++-
2 files changed, 44 insertions(+), 1 deletion(-)
Read that summary — it is the answer to "what did I just take on?":
Fast-forwardorMerge made by the 'ort' strategytells you which kind of merge happened (next lesson).- The file list is your test scope. Two files changed here; a merge that lists forty is a different afternoon.
- The insertion and deletion counts give you a rough size.
Predicting the Outcome
You do not have to run a merge to find out what it will do.
git log main..feature/auth-test --oneline
The commits that are on the feature branch and not on main — what the merge would bring in.
git diff main...feature/auth-test
Three dots. This shows what the feature branch changed since the merge base — not the difference between the two tips. It is the diff a Pull Request shows you, and it is the one you want when reviewing.
git merge --no-commit --no-ff feature/auth-test
A dry run in the strictest useful sense: it performs the merge in your working directory but stops before committing, so you can inspect the result. Undo it completely with:
git merge --abort
When Nothing Happens
Already up to date.
This means the source branch's commits are all already contained in your current branch. Nothing to do, nothing changed. It is not an error — it usually means someone merged this branch already, or you are on the wrong branch.
Pro Tip: For a tester, the file list a merge prints is the single most useful sentence in the output. Copy it into your notes before you start testing — it is your risk-based test scope for this build.
Key Takeaways
- You always merge into the branch you are currently on; the source branch is unchanged
- Git compares three commits: the merge base and both branch tips
- Changes to different files or different regions combine automatically; the same lines produce a conflict
- The merge summary's file list is your test scope — read it
git log main..branchandgit diff main...branchpreview a merge without performing it- "Already up to date" means the work is already contained, not that something failed