Photo by Eric Er on Unsplash

On this page

This chapter follows Undoing and moving changes.

Both merge and rebase bring work from one branch into another. Merge preserves the exact commit graph you had on the feature branch. Rebase copies commits onto a newer base and leaves the old commits unreachable. That difference drives code review, CI, and the golden rule about public history.

Vocabulary

You created branch feature from main. To integrate feature into main:

  • Source branch: where the work lived (feature).
  • Target branch: where you want the result (main).

Check out the target, then integrate the source:

Terminal window
git switch main
git merge feature

Merging feature into main while standing on feature with git merge main is the opposite direction—it brings main into feature, which is valid for updating a long-lived feature branch, not for landing the feature on main.

Fast-forward merge

If main did not move since you branched, Git can move the main pointer forward without a merge commit:

Diagram 1
gitGraph
  commit id: "c1"
  commit id: "c2"
  branch feature
  checkout feature
  commit id: "c3"
  checkout main
  merge feature id: "ff" type: FAST_FORWARD
Terminal window
git switch main
git merge feature

Three-way merge and conflicts

When both branches changed, Git creates a merge commit with two parents:

Diagram 2
gitGraph
  commit id: "base"
  branch feature
  checkout feature
  commit id: "f1"
  checkout main
  commit id: "m1"
  merge feature id: "merge1"
Terminal window
git merge feature

If the same lines changed, Git stops with unmerged paths. Open each file, remove conflict markers (<<<<<<<, =======, >>>>>>>), keep the intended result, then:

Terminal window
git add resolved-file.ts
git commit

Abort if you need to start over:

Terminal window
git merge --abort

Fetch latest remotes before merging shared branches. A merge commit should combine existing work, not sneak in new feature edits—make those commits on the feature branch first, then merge.

Squash merge

To land all feature work as one commit on main without replaying every intermediate commit:

Terminal window
git switch main
git merge --squash feature
git commit -m "Add login with OAuth"

History on main shows a single commit; feature is unchanged until you delete it.

What rebase does

Rebase replays your commits on top of another tip. Old commits become orphaned until garbage collection.

Diagram 3
gitGraph
  commit id: "base"
  branch feature
  checkout feature
  commit id: "f1"
  commit id: "f2"
  checkout main
  commit id: "m1"
  checkout feature
  commit id: "f1r"
  commit id: "f2r"

After git switch feature and git rebase main, commits f1 and f2 are replaced by new commits (new hashes) on top of m1.

Steps Git performs conceptually:

  1. Find the merge-base of feature and main.
  2. Temporarily detach replayable commits from feature.
  3. Reset feature to main.
  4. Cherry-pick each commit onto feature.

Merging feature into main afterward is often a fast-forward because main is simply behind feature’s replayed tip.

Interactive rebase and squashing

Clean up local history before opening a pull request:

Terminal window
git merge-base feature main
git rebase -i $(git merge-base feature main)

In the editor, change pick to squash (or s) for commits to fold into the previous one. Resolve conflicts with git rebase --continue or abort with git rebase --abort.

The golden rule

Do not rebase commits that others have already pulled.

Rebase rewrites hashes. Anyone who built on your old commits gets duplicate work and painful recovery. Rebase private branches; merge or revert on shared default branches unless the whole team agrees on rebasing shared lines.

When to merge

  • Integrating into main on GitHub with a merge commit preserves branch context.
  • Long-lived branches where everyone expects explicit merge nodes.
  • You want zero history rewrite on the shared remote.

When to rebase

  • Updating a local-only feature branch before review so diffs read top-to-bottom against latest main.
  • Squashing WIP commits before push -u the first time.
  • Linear history policies on the feature branch (still merge or squash at the end per team rules).

Pull requests on GitHub can merge, squash, or rebase and merge—each maps to the ideas above (Pull requests with and without GitHub).

Next: Advanced Git.

Check your understanding

Question 1 of 9

0 of 9 checked

  1. 1. To merge feature into main, where should you stand before git merge feature?

Search articles

Type a word to search published articles.

Open the search page