Git
Beginner 13 min read Git

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.

branchmergefast-forwardmerge commitconflictHEAD
Introduction

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.

Motivation

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.
Think about it

Mental model

Imagine

A bookmark in a book

Think of

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.

Mechanics

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.

main
git switch -c feature
feature commits
main also commits
git merge feature
Merged history
Reference

Key commands

git branch

List local branches; the asterisk marks the current one.

git switch -c feature/login

Create a branch named feature/login and switch to it in one step.

git switch main

Move HEAD back to the main branch.

git merge feature/login

Integrate the feature branch into the current branch.

git branch -d feature/login

Delete a branch that has already been merged.

git log --oneline --graph --all

Visualize branch structure and divergence.

Hands-on

Examples

Resolving a merge conflict

Resolving a merge conflict
git switch main
git 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:
<<<<<<< HEAD
deploy_target: production
=======
deploy_target: staging
>>>>>>> feature
# Edit the file to keep the correct value, then:
git add config.yml
git commit

Git 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.

Real world

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.
Guidelines

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.
Watch out

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.
Root cause analysis

Common issues

Error
Automatic merge failed; fix conflicts and then commit the result
Root cause

Both branches modified the same lines in a file.

Fix

Open the conflicted file, keep the correct content, remove markers, then git add and git commit.

Error
fatal: 'feature' is not a commit and a branch 'feature' cannot be created from it
Root cause

Typo in the branch name, or the branch does not exist locally.

Fix

Run git branch to list existing branches and use the exact name.

Error
fatal: Not possible to fast-forward, aborting
Root cause

You requested a fast-forward merge but the histories diverged.

Fix

Drop --ff-only and allow a regular three-way merge, or rebase first to make it linear.

When things break

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.
Interviews

Interview checkpoint

Practice

Hands-on lab

Branch, Merge and Resolve a Conflict
30 min · beginner
In progress
Objectives
  • 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

0/6 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/3
1

Which command creates a branch AND switches to it?

2

A fast-forward merge always creates a merge commit.

3

What does Git do when two branches changed the same line in the same file?

Quick reference

Cheat sheet

Branching & merging
git branchList branches
git switch -c nameCreate + switch
git switch mainSwitch branches
git merge branchMerge into current branch
git branch -d nameDelete merged branch
git merge --abortCancel a conflicted merge
Go deeper

Official documentation