Merging brings finished work back into main. In this lesson you will learn how Git decides between fast-forward and three-way merges, use the most important merge options, check what will be merged, and clean up afterwards.
๐ What You’ll Learn: how merging works, fast-forward merges, three-way merges and merge commits, –no-ff, –ff-only, –squash and –abort, –no-ff vs squash and GitHub’s merge buttons, checking branches before and after a merge, and cleaning up merged branches.
๐ What Does Merging Do?
When the work on a branch is finished, you merge it into another branch, usually main. Git combines the histories and the changes. You always merge into the branch you are currently on:
git switch main # 1. go to the branch that should receive the changes
git pull # 2. make sure it is up to date
git merge feature/login-tests # 3. bring the feature in
Depending on the history, Git performs one of two kinds of merge.
โฉ Fast-Forward Merge
If main has no new commits since the branch was created, Git simply moves the main pointer forward. No merge commit is created.
Before: After git merge feature:
C1 โโ C2 โ main C1 โโ C2 โโ C3 โโ C4 โ main, feature
\
C3 โโ C4 โ feature
Updating 8b1d4e2..7e2f1a9
Fast-forward
tests/login.spec.ts | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
๐บ Three-Way Merge
If both branches have new commits, Git looks at three snapshots (the common ancestor and the two branch tips) and creates a new merge commit with two parents.
Before: After git merge feature:
C1 โโ C2 โโ C5 โ main C1 โโ C2 โโ C5 โโโโ M โ main
\ \ /
C3 โโ C4 โ feature C3 โโ C4 โ feature
Git opens your editor with a default message like “Merge branch ‘feature/login-tests'”; save and close to finish. If both branches changed the same lines, Git stops with a conflict instead; see Resolve Merge Conflicts.
๐๏ธ Merge Options
| Command | Result |
|---|---|
git merge feature | Fast-forward if possible, otherwise a merge commit |
git merge --no-ff feature | Always create a merge commit, keeping the branch visible in history |
git merge --ff-only feature | Merge only if a fast-forward is possible; otherwise stop |
git merge --squash feature | Combine all branch changes into staged changes; you then make one normal commit |
git merge --abort | Cancel a merge that stopped with conflicts and go back to the state before |
–no-ff vs –squash
--no-ff | --squash | |
|---|---|---|
| Commits from the branch kept in main’s history | โ All of them | โ Replaced by one new commit |
| Merge commit | โ | โ |
| Readable history of main | Detailed | Compact, one commit per feature |
| GitHub equivalent | “Create a merge commit” | “Squash and merge” |
GitHub’s three pull-request merge buttons (merge commit, squash and merge, rebase and merge) map to these strategies; see Pull Requests Step by Step.
๐ Check Before and After Merging
git log --oneline main..feature/login-tests # commits that will come in
git diff main...feature/login-tests # changes on the branch since it split from main
git branch --merged # branches already merged into the current branch
git branch --no-merged # branches with unmerged work
git log --oneline --graph --all # see the result
๐งน After Merging
git push # publish the merged main
git branch -d feature/login-tests # delete the merged branch locally
git push origin --delete feature/login-tests
๐งญ Merge vs Rebase (Preview)
Merging preserves history exactly as it happened and is always safe for shared branches. Rebasing rewrites a branch so it looks as if it started from the latest main, giving a linear history. The full comparison is in git rebase and rebase vs merge.
๐ Assignment
- Create
feature/afrommain, make two commits, switch tomainand merge. Confirm it was a fast-forward. - Create
feature/b, commit on it, then commit something different onmain. Mergefeature/band inspect the merge commit withgit log --oneline --graph. - Repeat with
--no-ffon a branch that could fast-forward and compare the graphs. - Merge a branch with three commits using
--squashand commit the result with one message. - Use
git branch --mergedto find branches you can safely delete, and delete them.
โ FAQ
๐ค How do I merge a branch into main?
Switch to main (git switch main), update it (git pull), then run git merge branch-name and push.
๐ค What is a fast-forward merge?
A merge where the target branch has no new commits, so Git just moves its pointer forward to the branch tip without creating a merge commit.
๐ค What does git merge –no-ff do?
It always creates a merge commit, even when a fast-forward is possible, so the feature branch remains visible in history.
๐ค How do I cancel a merge?
If the merge stopped with conflicts, run git merge --abort. If it already completed and was not pushed, git reset --hard HEAD~1 removes it; if pushed, use git revert -m 1 <merge-commit>.
๐ค What is the difference between merge and squash merge?
A normal merge keeps every commit from the branch. A squash merge combines them into a single new commit on the target branch.
๐ฏ Next Steps
- ๐งฏ Resolve Merge Conflicts Step by Step
- ๐งฌ git rebase and Rebase vs Merge
- ๐ Git and GitHub Tutorial: full course
๐ฌ Learn Git and GitHub step by step: watch the series on YouTube!
Subscribe to SqaToolsByDY • Practice on sqatools.in
1 thought on “git merge Explained: Fast-Forward, Three-Way, –no-ff and Squash Merges”