Branching & Merging Strategies

TL;DR

Branches let you work on features in isolation. Merge preserves history, rebase keeps it linear. Use Git Flow for release-based projects and trunk-based development for CI/CD speed. Always resolve conflicts carefully — never just accept one side blindly.

Explain Like I'm 12

Imagine you're building a LEGO castle with friends. Instead of everyone working on the same castle at once (chaos!), each person takes a copy of the instructions and builds their section separately. When they're done, you snap the pieces together.

Branching = everyone working on their own section. Merging = snapping the pieces together. Sometimes two people built the same tower differently — that's a conflict, and you have to decide which version to keep.

How Branching Works

Every branch is just a lightweight pointer to a commit. Creating a branch is instant — Git doesn't copy files, it just creates a new pointer.

Diagram showing Git branching: main branch with commits, feature branch diverging, parallel commits on both, then merging back into main

Merge vs Rebase

The two main ways to integrate changes from one branch into another:

AspectMergeRebase
How it worksCreates a merge commit joining two branchesReplays your commits on top of the target branch
HistoryPreserves full branch history (non-linear)Creates a clean, linear history
SafetySafe — never rewrites historyRewrites commit SHAs — dangerous on shared branches
Best forShared branches, PRs, releasesLocal cleanup before pushing, keeping up with main
Conflict resolutionResolve once during mergeMay need to resolve at each replayed commit
# Merge: creates a merge commit
git switch main
git merge feature/login
# Creates commit: "Merge branch 'feature/login' into main"

# Rebase: replays commits on top of main
git switch feature/login
git rebase main
# Moves feature commits after latest main commit
git switch main
git merge feature/login  # Now a fast-forward (linear)
Warning: Never rebase commits that have been pushed to a shared branch. Rebase rewrites commit SHAs, which causes problems for anyone who already has those commits. The golden rule: rebase local, merge shared.

Branching Strategies

Git Flow

A structured model with dedicated branches for features, releases, and hotfixes. Best for projects with scheduled releases.

BranchPurposeMerges Into
mainProduction-ready code, tagged with versions
developIntegration branch for next releasemain (via release)
feature/*New featuresdevelop
release/*Release prep (bug fixes, versioning)main + develop
hotfix/*Emergency production fixesmain + develop
Info: Git Flow works well for mobile apps, libraries, and software with version numbers. It's overkill for web apps that deploy continuously.

Trunk-Based Development

Everyone commits to main (the trunk) directly or via very short-lived branches (< 1 day). Best for teams practicing continuous delivery.

# Short-lived feature branch
git switch -c feat/add-button
# ... make changes, commit ...
git push origin feat/add-button
# Open PR, get review, merge same day
# Delete branch after merge
Tip: Trunk-based dev requires good CI (tests run on every push) and feature flags to hide incomplete work. Google, Facebook, and Netflix use this model.

GitHub Flow

A simplified model: main is always deployable, features go in branches, PRs are the review mechanism. The most common model for GitHub projects.

  1. Create a branch from main
  2. Make commits
  3. Open a pull request
  4. Review + discuss
  5. Merge to main
  6. Deploy

Resolving Merge Conflicts

Conflicts happen when two branches change the same lines. Git marks the conflicting sections:

<<<<<<< HEAD
const greeting = "Hello, World!";
=======
const greeting = "Hi there!";
>>>>>>> feature/new-greeting

To resolve:

  1. Open the conflicted file and choose the correct code (or combine both)
  2. Remove the conflict markers (<<<<<<<, =======, >>>>>>>)
  3. Stage and commit the resolved file
# After manually editing the file:
git add src/greeting.js
git commit -m "Resolve conflict: use combined greeting"
Warning: Don't blindly accept "ours" or "theirs." Read both versions, understand the intent, and combine if needed. Blindly accepting one side can silently lose important changes.

Cherry-Pick

git cherry-pick copies a specific commit from one branch to another — without merging the whole branch.

# Apply a specific commit to current branch
git cherry-pick a1b2c3d

# Cherry-pick without committing (stage only)
git cherry-pick --no-commit a1b2c3d
Tip: Cherry-pick is great for hotfixes — apply a bug fix from develop to main without merging everything else.

Test Yourself

When should you use rebase instead of merge?

Use rebase on local, unpushed branches to keep history clean — e.g., before opening a PR, rebase onto the latest main. Use merge for shared branches and pull requests where preserving the full history matters. Golden rule: rebase local, merge shared.

What's the difference between Git Flow and trunk-based development?

Git Flow uses long-lived branches (develop, release, hotfix) and is suited for versioned releases. Trunk-based development uses short-lived branches (< 1 day) merged frequently into main, suited for continuous deployment. Git Flow trades simplicity for release control; trunk-based trades control for deployment speed.

What does git cherry-pick do?

git cherry-pick takes a specific commit (by SHA) from one branch and applies it to your current branch as a new commit. It doesn't merge the whole branch — just that one commit. Useful for applying hotfixes or specific changes selectively.

How do you resolve a merge conflict?

(1) Open the conflicted file — Git marks conflicts with <<<<<<<, =======, >>>>>>> markers. (2) Edit the file to keep the correct code and remove the markers. (3) Stage the resolved file with git add. (4) Complete the merge with git commit.

Why is rebasing dangerous on shared branches?

Rebase rewrites commit SHAs — it creates new commits with new hashes. If others have already pulled the original commits, their history diverges from yours. They'll see duplicate or conflicting commits when they pull. This can cause data loss and confusion across the team.

Interview Questions

Explain the difference between a fast-forward merge and a three-way merge.

A fast-forward merge happens when the target branch hasn't diverged — Git just moves the pointer forward. No merge commit is created. A three-way merge happens when both branches have new commits — Git compares the common ancestor, the source tip, and the target tip, then creates a merge commit combining both.

Your team uses Git Flow. A critical bug is found in production. Walk through the process to fix it.

(1) Create a hotfix/fix-critical-bug branch from main. (2) Fix the bug and commit. (3) Merge the hotfix into main and tag the release. (4) Also merge the hotfix into develop so the fix carries forward. (5) Delete the hotfix branch.

What is git rebase --interactive used for?

Interactive rebase (git rebase -i) lets you edit, squash, reorder, or drop commits in your branch history. Common uses: squash multiple WIP commits into one clean commit before a PR, reword commit messages, or remove accidental commits. Only use on local/unpushed branches.