Gitgit rebase Command

git rebase Command

git rebase moves your branch’s commits to start from a different commit, creating new commits with new hashes but the same content. The result is a linear history — your work appears to have always been built on top of the latest base.

The simplest rebase

Move feature-x onto current main

Bash
# Make sure main is up to date first
git switch main
git pull

# Rebase your branch onto main
git switch feature-x
git rebase main

Read this as: “take feature-x and replay its commits on top of main.”

What Git actually does
  • Finds the common ancestor of feature-x and main.

  • Records the diffs of every commit on feature-x that is not in main.

  • Resets feature-x to the tip of main.

  • Re-applies each recorded diff as a NEW commit (new SHA, new parent, same content).

  • If a diff fails to apply cleanly → conflict; you fix and continue.

Before and after

Before

Text
         A───B───C───F   ◀── main
                  \
                   D───E       ◀── feature-x

After 'git rebase main' (on feature-x)

Text
         A───B───C───F───D'───E'   ◀── feature-x

D and E are now D' and E' — same content, new SHAs, new parents.
The old D and E are unreachable, kept in reflog for a while.
Aborting and continuing

Bash
# Resolved a conflict; continue replay
git rebase --continue

# Skip the current commit (use with care)
git rebase --skip

# Cancel everything; restore pre-rebase state
git rebase --abort
Conflicts during rebase

Each replayed commit can conflict separately. The conflict-resolve cycle is identical to a normal merge, but notice that --ours and --theirs are swapped during a rebase:

  • --ours — the branch you are rebasing onto (here: main).

  • --theirs — your branch (the commits being replayed).

Why the flip?
During rebase, Git pretends you started from `main` and is replaying *your* commits on top — your work is the “incoming” side. So `--theirs` means your work. Awkward, but consistent.
--onto for precision

Move only the commits in a range

Bash
# Take everything on feature-x that's not on old-base
# and replay it onto new-base.
git rebase --onto new-base old-base feature-x

See the dedicated --onto page for the full picture.

Interactive rebase

Bash
git rebase -i main
# Opens an editor letting you pick/reword/squash/drop each commit

Interactive rebase is the polish-your-history tool. See its own page.

Pulling with rebase

Avoid merge commits on pull

Bash
git pull --rebase
# Equivalent to: git fetch + git rebase origin/<branch>

# Configure as default
git config --global pull.rebase true
Pushing after a rebase

Force-push the rewritten branch

Bash
# Safer: refuses if the remote moved unexpectedly
git push --force-with-lease

# Older / more dangerous
git push --force
Warning
Force-push **only branches that are yours** (no one else works on them). If you force-push to a shared branch like `main`, you can erase teammates’ commits.
Useful options
  • --keep-empty — keep commits that became empty after rebasing (default is to drop them).

  • --autosquash — used with -i, automatically positions fixup! and squash! commits.

  • --autostash — stash uncommitted changes before rebasing, pop after.

  • --exec "cmd" — run a command after each commit (useful to run tests on every replayed commit).

  • -r / --rebase-merges — preserve the topology of merge commits during rebase.

Inspecting before rebasing

What will be replayed?

Bash
git log main..feature-x --oneline
# Lists the commits that will be re-applied
Tip
Set up git config --global rerere.enabled true. “Rerere” = reuse recorded resolution. The next time the same conflict appears (very common during long rebases), Git resolves it automatically.