Branching & Merging
A branch is just a movable pointer to a commit. Understand fast-forward vs three-way merges, how to switch branches safely, and how to resolve conflicts when two branches change the same lines.
What is this?
A branch is a lightweight pointer to a commit. Creating a branch does not copy files — it just adds a pointer at the current HEAD. Merging integrates two lines of history, either with a fast-forward (linear) or a merge commit (three-way). A conflict occurs when both branches changed the same lines.
Why do you need it?
- Branches isolate work in progress so main always stays deployable.
- They are almost free: creating a branch is just writing a 40-character pointer.
- Parallel development lets multiple people and features proceed without stepping on each other.
- Pull requests on branches provide review gates before changes reach main.
Mental model
A bookmark in a book
A branch
A bookmark lets you continue reading from any page without losing your place. A branch lets you continue working from any commit without disturbing the main line of history.
How it works
- git branch <name> creates a new pointer at the current commit; git switch <name> moves HEAD to that branch.
- Every new commit advances the pointer of the branch you are on.
- git merge <branch> integrates that branch's commits into your current branch.
- If your branch has not diverged, Git fast-forwards — it just moves the pointer, with no merge commit.
- If both branches changed the same lines, Git stops with a conflict: edit the file, git add it, then commit to finish the merge.
Fast-forward vs three-way merge.
Key commands
git branchList local branches; the asterisk marks the current one.
git switch -c feature/loginCreate a branch named feature/login and switch to it in one step.
git switch mainMove HEAD back to the main branch.
git merge feature/loginIntegrate the feature branch into the current branch.
git branch -d feature/loginDelete a branch that has already been merged.
git log --oneline --graph --allVisualize branch structure and divergence.
Examples
Resolving a merge conflict
git switch maingit merge feature# Auto-merging config.yml# CONFLICT (content): Merge conflict in config.yml# Automatic merge failed; fix conflicts and then commit the result. # config.yml now contains conflict markers:<<<<<<< HEADdeploy_target: production=======deploy_target: staging>>>>>>> feature # Edit the file to keep the correct value, then:git add config.ymlgit commitGit cannot pick a winner between the two versions of config.yml, so it writes both with <<<<<<< / ======= / >>>>>>> markers and stops. You choose the correct content, stage the resolved file, and commit to finish the merge.
In production
- Feature branches isolate work in progress while main remains deployable at all times.
- Protected main branches require a passing CI run and code review before merge.
- Release branches freeze a version so stabilization does not block new feature work.
- Hotfix branches cut from main ship urgent fixes without pulling in unreleased features.
Best practices
- Keep branches short-lived and merge them quickly to limit divergence.
- Delete merged branches (git branch -d) to avoid a stale-branch graveyard.
- Use a naming convention like feature/, fix/ and chore/ so the branch communicates intent.
- Review the merge diff carefully; resolve conflicts deliberately, never by blindly choosing one side.
- Rebase or merge main into your feature branch regularly to keep it in sync and reduce conflict size.
Common mistakes
- Keeping long-lived feature branches that drift far from main, producing giant merges.
- Resolving every conflict by taking HEAD (your side) without reading the other side.
- Pushing directly to main instead of merging through a reviewed pull request.
- Merging main into a feature repeatedly, which litters history with noisy merge commits.
Common issues
Automatic merge failed; fix conflicts and then commit the resultBoth branches modified the same lines in a file.
Open the conflicted file, keep the correct content, remove markers, then git add and git commit.
fatal: 'feature' is not a commit and a branch 'feature' cannot be created from itTypo in the branch name, or the branch does not exist locally.
Run git branch to list existing branches and use the exact name.
fatal: Not possible to fast-forward, abortingYou requested a fast-forward merge but the histories diverged.
Drop --ff-only and allow a regular three-way merge, or rebase first to make it linear.
Debugging tips
- git status during a conflict shows unmerged paths in red and the merge state.
- git log --oneline --graph --all shows exactly how branches diverged.
- git merge --abort restores the pre-merge state if a conflict spirals out of control.
- git branch -vv shows each branch's upstream tracking branch and how far ahead/behind it is.
Interview checkpoint
Hands-on lab
- Create and switch between branches
- Merge a feature branch
- Provoke and resolve a merge conflict
- Visualize the merged history
Branch, Merge and Resolve a Conflict
30 min · beginner
Quick quiz
Which command creates a branch AND switches to it?
A fast-forward merge always creates a merge commit.
What does Git do when two branches changed the same line in the same file?
Cheat sheet
git branchList branchesgit switch -c nameCreate + switchgit switch mainSwitch branchesgit merge branchMerge into current branchgit branch -d nameDelete merged branchgit merge --abortCancel a conflicted merge