Git command reference · Reviewed 2026-08-16

git rebase: understand the history before you rewrite it

Learn git rebase through commit-graph reasoning, safe examples, conflict recovery, interactive cleanup, and practical guidance on when rebasing is the wrong choice.

git rebase [options] <upstream> [<branch>]

Start with the mental model

Rebase moves a line of commits so it appears to start from a different base commit. It can create a cleaner history, but because it rewrites commit identities, it should be used deliberately.

Predict before reading on

You have commits A → B → C on main. Your feature branch starts at B and adds D → E. If you rebase the feature onto C, do you still have the exact same D and E commits?

Reveal the reasoning

No. Git replays the changes from D and E after C, producing new commits—think D′ and E′—because their parent chain changed. The file changes may be equivalent, but the commit identities are not.

Before you use it

  • Know that a Git branch name points to a commit rather than containing a separate copy of files.
  • Be comfortable with git status, git log, commits, and switching branches.
  • Understand that changing a commit creates a new commit ID even when the file content looks similar.

A useful safety habit is to run git status and inspect a compact graph before a rebase. If you cannot explain which commits are local and which base you intend to move onto, stop there and inspect first.

Common options and what they really mean

-i, --interactive

Open a todo list so commits can be reordered, edited, squashed, or dropped.

Use it when: Cleaning a local feature branch before review.
--continue

Continue a paused rebase after conflicts are resolved and staged.

Use it when: After fixing files reported as conflicted during a rebase.
--abort

Stop the rebase and restore the branch to its pre-rebase state.

Use it when: When the conflict set is surprising or you want to reconsider the approach.
--skip

Omit the currently replayed commit and continue.

Use it when: Only when you have verified that the commit is genuinely unnecessary, often because its change already exists upstream.

Worked examples

Example 1

Beginner: replay your feature work on the latest main

Situation: Your feature branch has two local commits while main has advanced by one commit. You want your feature commits to sit after the new main commit.

git switch feature/login
git rebase main

Git finds the commits that are unique to feature/login, temporarily removes them, moves the branch base to main, and then replays those feature commits in order. The replayed commits receive new IDs.

Typical success output:

Successfully rebased and updated refs/heads/feature/login.
Example 2

Practical: update a branch from the remote main line

Situation: You are about to open a pull request and want to incorporate the latest remote main without adding a merge commit to your local feature history.

git fetch origin
git rebase origin/main

Fetching first updates your remote-tracking references without changing your working branch. Rebasing onto origin/main then uses the exact remote state you just fetched as the new base.

Example 3

Advanced: clean up the last four local commits

Situation: A feature works, but the history contains temporary fixup commits and an unclear message.

git rebase -i HEAD~4

Interactive rebase opens a todo list for the selected commits. Use actions such as reword, squash, fixup, or drop only after you understand how each commit contributes to the final change. This rewrites every affected commit from the first changed point onward.

Conflict recovery: slow down instead of guessing

When a replayed commit does not apply cleanly, Git pauses. That pause is useful: it tells you the old change and the new base disagree about the same area. Resolve the intent, not merely the conflict markers.

  1. Run git status and identify the files Git says are conflicted.
  2. Read the surrounding code and determine what the replayed commit was trying to accomplish.
  3. Edit the files so the result makes sense on the new base, then run relevant tests or checks.
  4. Stage resolved files with git add.
  5. Run git rebase --continue. If the entire approach is wrong, use git rebase --abort instead.

When this command goes wrong

Common mistakes and why they fail

Treating rebase as a harmless visual rearrangement

A rebase does not merely redraw the graph. Replayed commits are new objects with new parent relationships and therefore new commit IDs.

Safer response: Before rebasing important work, confirm the branch state with git status and git log. If a rebase is going wrong, git rebase --abort is usually the safest immediate exit.

Rebasing commits that teammates already use

If other people have based work on the old commit IDs, rewriting those commits can create duplicate-looking histories and painful reconciliation.

Safer response: Prefer merging for shared published history unless the team has explicitly agreed on a rebase workflow.

Resolving conflicts without checking the resulting behavior

A conflict resolution can produce syntactically valid files while accidentally changing intent. The fact that Git can continue does not prove the program is correct.

Safer response: After resolving and staging conflicts, run focused tests or inspect the affected behavior before git rebase --continue.

Using --skip because a conflict is inconvenient

Skipping discards the currently replayed commit from the new history. That can silently remove required behavior.

Safer response: Skip only after proving the change is already represented or intentionally obsolete.

Guided practice

Your branch has three local commits and origin/main has moved forward. You have not pushed your branch. What sequence gives you the latest remote base while keeping your local commits linear?

Hint

First update your knowledge of the remote without changing your branch. Then replay the local commits onto that remote-tracking branch.

Tutor answer
git fetch origin
git rebase origin/main

The important reasoning is that git fetch updates origin/main; it does not silently merge it. The rebase step then has an explicit, inspectable target.

Independent practice

Create a disposable repository with a main branch and a feature branch. Make main advance after the branch point, then make two feature commits. Draw the commit graph before rebasing, predict the graph after rebasing, run the rebase, and compare your prediction with git log --graph --oneline --decorate --all. Finally, inspect git reflog to find the feature branch’s previous tip.

Related commands

  • git status
  • git log --graph --oneline --decorate
  • git fetch
  • git reflog
  • git merge

These are intentionally listed as a small working set rather than a link dump. Status and graph inspection help you understand state; fetch updates remote knowledge; reflog helps recovery; merge is the main alternative when preserving shared history matters.

Frequently asked questions

Is rebase better than merge?

Neither is universally better. Rebase is useful for preparing a clean local line of work; merge preserves the true branch topology and is often safer for shared history. Choose based on collaboration rules and the history you need to preserve.

Why did my commit hashes change?

A commit ID includes information about its parent. Rebasing changes the parent chain, so the replayed commits become new commits even if their patches look identical.

What should I do when a rebase conflicts?

Read git status, resolve one conflicted file at a time, stage the resolved files, test the result where practical, then run git rebase --continue. Use git rebase --abort if the new history is not what you intended.

Can I undo a completed rebase?

Often yes if the earlier tip is still reachable through the reflog. Recovery is easier if you stop and inspect before doing additional destructive operations. Treat reflog recovery as a safety net, not the normal workflow.

Next step

Practice on disposable history before using rebase under pressure.

The safest way to become comfortable with rebasing is to predict commit graphs, perform the operation, inspect the result, and deliberately practice abort/recovery in a repository where nothing important can be lost.

Explore command references