By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
--no-ff
A hyper-practical, zero-fluff guide for engineers who need to merge branches safely in production.
You’re working on a feature branch (feature/login) while your teammate merges a critical bug fix (hotfix/auth) into main. When you try to merge your changes, Git throws a conflict—or worse, silently overwrites history. Merging strategies determine how Git combines branches, and picking the wrong one can: - Lose commit history (making debugging a nightmare).- Create messy, unreadable logs (hard to audit or roll back).- Accidentally overwrite changes (if you force a fast-forward when you shouldn’t).
feature/login
hotfix/auth
main
Real-world scenario:You’re a DevOps engineer maintaining a microservice. The main branch has a security patch, and your feature/payment branch has new logic. If you merge with --ff-only (fast-forward), Git might silently squash your work into main without a merge commit, making it impossible to track which changes belong to which feature. This matters because:- Auditors need clear history to verify compliance.- Rollbacks become risky if you can’t isolate changes.- Collaboration breaks if teammates can’t see what was merged when.
feature/payment
--ff-only
--ff
git log
A-B-C
feature
A-B-D
--squash
git mergetool
git status
Merge feature/login into main using a three-way merge with --no-ff to preserve history.
git checkout main git pull origin main # Ensure main is up to date git log --oneline --graph --all
Expected output:
* abc1234 (feature/login) Add login form | * def5678 (HEAD -> main) Fix auth bug |/ * 9876zyx Initial commit
✅ If main and feature/login share a common ancestor but have diverged, proceed.
git merge feature/login --ff-only
fatal: Not possible to fast-forward, aborting.
✅ This confirms the branches diverged—you must use a three-way merge.
git merge --no-ff feature/login -m "Merge feature/login into main"
Merge made by the 'ort' strategy. login.html | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 login.html
Verify the merge commit:
git log --oneline --graph -n 3
* 1a2b3c4 (HEAD -> main) Merge feature/login into main |\ | * abc1234 Add login form * | def5678 Fix auth bug |/ * 9876zyx Initial commit
✅ Success! The merge commit (1a2b3c4) is visible, preserving history.
1a2b3c4
git push origin main
⚠️ If branch protection rules exist, GitHub/GitLab may reject this unless: - You have admin rights.- The merge is approved (if PR required).
yaml # GitHub branch protection rule (in repo settings) require_pull_request_reviews: true require_linear_history: false # Allows merge commits
--depth=1
bash git tag -a v1.2.0 1a2b3c4 -m "Release 1.2.0" git push origin v1.2.0
git rerere
bash git config --global rerere.enabled true
git log --merges
bash git log --oneline --merges --since="2 weeks ago"
git rebase
git revert
git pull origin main
git merge
-m
fatal: Not possible to fast-forward
❌ Trap: "Git creates a merge commit" (wrong—--ff-only refuses to merge if it can’t fast-forward).
"When should you use --no-ff?"
❌ Trap: "Always" (wrong—trivial changes like typo fixes can use fast-forward).
"How do you undo a merge commit?"
git revert -m 1 <merge-commit-hash>
git reset --hard HEAD~1
# 1. Setup git init echo "Initial" > README.md git add README.md git commit -m "Initial commit" git checkout -b feature # 2. Diverge branches echo "Main change" >> README.md git commit -am "Update main" git checkout feature echo "Feature change" >> README.md git commit -am "Update feature" # 3. Fast-forward merge git checkout main git merge feature --ff-only # Fails (branches diverged) git merge feature # Creates a merge commit (three-way) # 4. Undo and redo with --no-ff git reset --hard HEAD~1 # Undo the merge git merge --no-ff feature -m "Merge feature with --no-ff"
Why it works:- --ff-only fails because main and feature diverged.- --no-ff forces a merge commit even if a fast-forward is possible.
git merge <branch>
git merge feature/login
git merge --no-ff
git merge --no-ff feature/login
git merge --ff-only
git merge --ff-only hotfix
git merge --squash
git merge --squash feature
git log --oneline --merges
git revert -m 1 <hash>
git revert -m 1 abc1234
git config --global rerere.enabled true
⚠️ Trap: --squash loses history—use only for local cleanup.⚠️ Default: git merge tries fast-forward first.
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.