Git Merge
Merging is the process of combining the changes from one branch into another. After finishing work on a feature branch, the changes are merged back into the main branch to become part of the stable codebase.
Real-life analogy: Think of two writers working on different chapters of a book. Once both finish, their chapters are combined into a single book. That combination is the merge.
main: A ──── B ──── C ────────────── G (Merge Commit)
\ /
feature: D ──── E ── F
Basic Merge Workflow
The target branch (the one receiving the changes) must always be the active branch before merging. To merge a feature branch into main:
# Step 1: Switch to the branch that will receive the changes
git switch main
# Step 2: Merge the feature branch into main
git merge feature-contact-form
Types of Merges
1. Fast-Forward Merge
A fast-forward merge happens when the target branch has not had any new commits since the feature branch was created. There is a straight, linear path from the base to the feature branch tip. Git simply moves the pointer forward — no merge commit is created.
Before:
main: A ──── B
\
feature: C ──── D (HEAD of feature)
After fast-forward merge:
main: A ──── B ──── C ──── D (HEAD of main)
git switch main
git merge feature-login
# Output:
Updating b7c3d45..a3f92b1
Fast-forward
login.html | 15 +++++++++++++++
1 file changed, 15 insertions(+)
2. Three-Way Merge (Merge Commit)
When both branches have diverged — meaning the main branch has new commits that the feature branch does not have — Git performs a three-way merge. It finds the common ancestor commit and combines the changes from both branches into a new "merge commit."
Before:
main: A ──── B ──── E
feature: A ──── B ──── C ──── D
After three-way merge:
main: A ──── B ──── E ──────── M (merge commit)
\ /
feature: C ──── D
git switch main
git merge feature-contact-form
# Output:
Merge made by the 'ort' strategy.
contact.html | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
A text editor opens to write the merge commit message. The default is fine — save and close the editor to complete the merge.
Creating a Merge Commit Even for Fast-Forward
Using the --no-ff flag forces a merge commit even when a fast-forward is possible. This preserves the fact that a feature branch existed:
git merge --no-ff feature-loginMany teams use this to maintain a clear history of feature development.
Merge Commit Message
By default, Git writes the merge commit message. A custom message can be provided:
git merge feature-login -m "Merge feature-login: add user authentication"Checking the Result
git log --oneline --graph --allOutput:
* a1b2c3d (HEAD -> main) Merge branch 'feature-login'
|\
| * d4e5f6g Add login form HTML
| * e7f8g9h Add login CSS
|/
* b7c3d45 Update homepage
Aborting a Merge in Progress
If a merge starts but needs to be cancelled (for example, to resolve conflicts later):
git merge --abortThis cancels the merge and returns the repository to the state it was in before the merge started.
Merge Strategies
| Strategy | Description |
|---|---|
Fast-Forward (--ff) | Default when no divergence — no merge commit, clean linear history |
No Fast-Forward (--no-ff) | Always creates a merge commit — preserves branch history |
Squash (--squash) | Combines all branch commits into one before merging |
Squash Merge Example
git merge --squash feature-small-fix
git commit -m "Apply small fix (squashed)"
All commits from the feature branch are combined into a single commit on main. Useful when a branch has many messy intermediate commits.
Deleting the Branch After Merging
After a successful merge, the feature branch is no longer needed and can be deleted:
git branch -d feature-contact-formOn GitHub, the PR merge page usually offers a "Delete branch" button right after merging.
Summary
Merging combines the work from one branch into another. A fast-forward merge creates a clean linear history when there is no divergence. A three-way merge creates a merge commit when both branches have diverged. Use --no-ff to always create merge commits and preserve branch history. After merging, delete the feature branch to keep the repository tidy.
