git merge
Intermediate Git CLI Careful
Summary: git merge <branch> brings that branch's commits into the branch you are on. Depending on the situation it moves the label forward (fast-forward), creates a merge commit with two parents, or, with --squash, stages everything as one change for you to commit.
Careful — merging cannot lose committed work, but it can stop mid-way on a conflict, and it merges into the branch you are on, which is the direction people get wrong. git merge --abort always returns you to the state before.
What it does
Finds the common ancestor of the two branches and combines the changes each side made since (lesson 11.1). Lines only one side changed are taken automatically; lines both sides changed differently become a conflict for you to resolve.
Why it exists
Parallel branches are only useful if they can be brought back together. Merge is the operation that does it while keeping both histories intact.
When to use it
- Bringing a finished branch into
main(though usually the merge request button does this). - Bringing
main's newer commits into your branch while you work (lesson 6.4). - Anywhere you would consider a rebase but the branch is shared.
When not to use it
- To keep history linear:
git rebase, on your own unshared branch. - To bring in one commit rather than a branch:
git cherry-pick. - On a protected
main: the platform's merge button, through a merge request.
Syntax
| Form | Meaning |
|---|---|
git merge <branch> |
Merge into the current branch; fast-forward when possible |
git merge --no-ff <branch> |
Always create a merge commit |
git merge --ff-only <branch> |
Only if it is a fast-forward; otherwise stop and change nothing |
git merge --squash <branch> |
Stage the whole branch as one change; you then commit |
git merge --abort |
Undo a merge that stopped on a conflict |
git merge --continue |
Finish after resolving (same as git commit) |
git merge --no-edit <branch> |
Accept the default merge message without opening the editor |
Examples
A fast-forward, when main gained nothing meanwhile:
$ git switch main
$ git merge docs/12-windows-install-stepsUpdating 1a01760..5f181fc
Fast-forward
docs/getting-started.md | 4 ++++
1 file changed, 4 insertions(+)A merge commit, forced with --no-ff:
$ git merge --no-ff docs/33-faq-windowsMerge made by the 'ort' strategy.
docs/faq.md | 4 ++++
1 file changed, 4 insertions(+)A squash, which stages but does not commit:
$ git merge --squash feature/21-difficulty-filterUpdating 87c5ee6..059253c
Fast-forward
Squash commit -- not updating HEAD
docs/filter.md | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 docs/filter.md$ git status -sA docs/filter.mdA conflict, and the way out:
$ git merge mainAuto-merging docs/faq.md
CONFLICT (content): Merge conflict in docs/faq.md
Automatic merge failed; fix conflicts and then commit the result.$ git merge --abortExpected result
Fast-forward: the branch label moves, no commit. Merge commit: one new commit with two parents. Squash: staged changes and no commit. Conflict: the merge pauses, git status says "You have unmerged paths", and nothing is committed until you finish or abort.
Try it here
The simulator below runs a small model of Git in the page. Nothing here touches a real repository, so try the command, then try it wrong (lesson 2.8 explains it).
The Git state simulator loads here.
Common mistakes
- Merging in the wrong direction.
git merge mainwhile on your branch updates your branch. To put your work intomain, switch tomainfirst (or use the merge request). - Forgetting to pull first. Merging into a stale
mainmerges into an old state. git branch -drefusing after a squash merge. Expected; the branch's own commits are not inmain. Use-Donce you have confirmed.- Panicking at a conflict.
git merge --abortis complete and safe. - Expecting
--squashto commit. It deliberately leaves the message to you.
How to undo or recover
- Mid-conflict:
git merge --abort. - A completed merge that has not been pushed:
git reset --hard HEAD~1returns to before it Dangerous — it discards uncommitted work too, so checkgit statusfirst. - A merge that has been pushed:
git revert -m 1 <merge-hash>, which adds a commit undoing it (lesson 12.6).
In VS Code
Command Palette → Git: Merge Branch…. Conflicts open the merge editor; Git: Abort Merge cancels.
In IntelliJ IDEA
Branches popup → point at a branch → Merge into current, with --no-ff and squash variants in the same menu. Conflicts open the three-pane merge tool; Git → Abort Merge cancels.
Related commands
git rebase is the linear alternative · git pull is fetch plus merge · git switch puts you on the receiving branch first · git revert undoes a pushed merge.
Lessons that use this command
Merging: fast-forward, merge commit, squash · Publish, track, update from main · Resolve in the terminal · Lab 3 · Lab 4.