GitIntroduction to Merging

Introduction to Merging

Merging is how you bring two lines of work back together. You created a branch, did some work, and now you want those changes to flow back into main (or any other branch). Git has surprisingly clever algorithms for this — but the basic idea is simple: take the commits from one branch and apply them on top of another.

The big picture

Before the merge

Text
        A───B───C   ◀── main
                 \
                  D───E   ◀── feature

After 'git merge feature' on main

Text
        A───B───C───────M   ◀── main
                 \     /
                  D───E       ◀── feature

M is the merge commit — a special commit with two parents (C and E). It marks the point where the two branches reunited.

The basic workflow

Merge feature INTO main

Bash
# 1. Make sure your destination branch is up to date
git switch main
git pull

# 2. Merge the feature branch in
git merge feature

# 3. Push
git push

Notice the direction: you git switch to the destination branch (the one that should absorb the changes), then git merge the source branch you want to pull in.

Three kinds of merges
  • Fast-forward — the destination has not moved since the source branched off. Git can just slide the pointer forward. No merge commit is created.

  • Three-way merge (true merge) — both branches have new commits. Git creates a new merge commit with two parents.

  • Conflict — both branches changed the same lines. Git stops and asks you to resolve.

When Git can fast-forward

Fast-forward setup

Text
        A───B───C        ◀── main (HEAD)
                 \
                  D───E    ◀── feature

After 'git merge feature':
        A───B───C───D───E    ◀── main, feature

main simply moves forward to point at E. No merge commit is needed because feature already includes every commit on main. Fast-forward merges keep history linear.

When Git creates a merge commit

Three-way merge setup

Text
        A───B───C───F   ◀── main (HEAD)
                 \
                  D───E       ◀── feature

After 'git merge feature':
        A───B───C───F───M   ◀── main
                 \     /
                  D───E       ◀── feature

Because main has commit F that feature does not, Git cannot fast-forward. It creates a merge commit M that combines the two timelines.

Why the “three-way” name?

To produce the merge, Git compares three snapshots: the common ancestor (here C), and each branch tip (F and E). It computes the changes each side made since C and combines them. The middle commit is what tells Git who changed what.

What about conflicts?

If both branches changed the same lines of the same file in different ways, Git cannot decide which version to keep. It stops the merge, marks the conflicting hunks in the files, and asks you to fix them. See the “Merge Conflicts” page for the recovery procedure.

The lifecycle of a feature

The full loop

Bash
# Start clean
git switch main
git pull

# Branch off
git switch -c feature-search

# Work, commit, work, commit
git add . && git commit -m "Add search component"
git add . && git commit -m "Wire search to API"

# Push for review
git push -u origin feature-search

# After PR is approved, merge (locally or on GitHub):
git switch main
git pull
git merge feature-search    # ← the moment
git push

# Clean up the merged branch
git branch -d feature-search
Merging on GitHub vs locally
  • On GitHub you open a Pull Request and click “Merge”. Behind the scenes GitHub runs a merge on its servers.

  • GitHub offers three flavours: regular merge, squash merge, or rebase + fast-forward. Most teams pick one for the whole repo.

  • Locally, git merge does the same thing but on your machine — useful for personal branches, hotfixes, or after a force-push when GitHub gets confused.

Merge vs rebase

Both bring work from one branch into another, but in different ways:

  • Merge keeps both timelines and adds a join commit. History becomes a graph.

  • Rebase replays your commits on top of the other branch. History becomes linear.

  • Some teams prefer merge for honesty (it reflects what happened); some prefer rebase for cleanliness. See the “Rebase vs Merge” page for the deep dive.

Merging is local until you push
Like every Git operation, `git merge` only modifies your local repo. The merge is invisible to teammates until you `git push`.
Tip
Always merge from a clean working tree. Run git status first. Merging on top of half-staged changes is the easiest way to confuse yourself.