A Complete Guide to Using Git Rebase with Examples

Git-Rebase-feature.jpg
Key Takeaways:
  • Many developers hear about Git Rebase with a warning that it can “ruin commit history,” which makes some avoid it.
  • When used correctly, Git Rebase is safe and very powerful for maintaining a clean project history.
  • Rebase reapplies your commits on top of the latest branch updates, creating a linear history instead of multiple merge commits.
  • The main caution is that rebase rewrites commit history. Running it on the wrong branch or without care can cause conflicts or lost work.
  • It’s most useful when you want a straightforward, readable history without extra merge clutter.
  • Rebase is not a replacement for merging but a complementary tool for keeping branches up to date before integration.
  • Use it carefully when collaborating with others—especially avoid rebasing public/shared branches.
  • Following a step-by-step approach ensures safe usage and helps maintain consistency across the project.
  • With practice, Git Rebase becomes a powerful ally for clean workflows and effective collaboration.

Table of Contents:

What is Git Rebase?

Git Rebase is a Git command that reapplies commits from your current branch onto the tip of another branch (or any target commit). Instead of creating a merge commit, it rewrites the branch history so it appears as if your work started from the newest version of the target branch. 

“Git Rebase is a Git command used to integrate changes from one branch into another by moving your commits to the latest commit (tip) of the target branch”.

Git Rebase

Unlike git merge, which creates a new merge commit and keeps the branching structure intact, rebase rewrites commit history. So, it looks as if your work started from the most recent state of the target branch.

The result is a clean, linear project history without unnecessary merge commits. The code itself remains the same, but the sequence of commits is reorganized. Since rebase creates new commit hashes, it should be used carefully. It should be avoided on public branches that others may already be using.

Git Rebase Syntax

git checkout <feature-branch>
git rebase <base-branch>
  • <feature-branch>: branch that contains the commits to move.
  • <base-branch>: branch onto which the commits will be reapplied, often main or master.

This updates the feature branch so its commits sit directly on top of the latest commit in the base branch.

When to Use Git Rebase

Git rebase is useful when you want to update your branch with the latest work from the main branch while maintaining a linear history. Instead of merging, which adds an extra commit, rebase moves your changes so they appear as if they were created after the newest commits on the target branch. Let’s understand it with an example.

How Git Rebase Works

Suppose you are building a search feature while your teammate updates the main branch with a security fix. Your branch is now behind the latest version of the project. Rebasing helps you move your commits on top of the updated main branch.

Visual Working of Git Rebase with Example

How Git Rebase Works

Before Rebase

Before Rebase
  • M1 → M2 → M3 → M4 are commits on the main branch.
  • F1 → F2 are commits on the feature branch created from M2.
  • At this point, the feature branch is outdated because main has moved ahead (M3, M4).

Run Rebase:

git checkout feature
git rebase main

After Rebase

Main:    M1 → M2 → M3 → M4 → F1′ → F2′

  • Commits F1 and F2 are replayed on top of M4.
  • They become new commits F1′ and F2′.
  • The history is now linear, making it look as if the feature branch was based on the latest main branch.

What Happens Internally

  • Git finds the common ancestor (M2).
  • Temporarily removes your commits (F1, F2).
  • Updates the branch to the latest main (M3, M4).
  • Reapplies your commits as new

Types of Git Rebase

Git rebase can run in two modes: Standard and Interactive. The difference comes down to whether you use the -i flag, while we have a third type, too. Let’s discuss them first to understand Git Standard vs Git Interactive Rebase. 

1. Interactive Rebase (git rebase -i)

Interactive rebase allows you to edit your commit history before it’s finalized. You can reorder commits to follow a logical sequence, git squash several commits into one, or adjust commit messages for clarity. This is especially useful when you want your branch history to look polished before merging it into the main branch. Instead of just replaying commits, you can decide what happens to each one. 

With it, you can:

  • Reorder commits to arrange them in a logical sequence.
  • Git Squash commits to combine multiple small commits into one.
  • Edit commit messages to fix typos or add more clarity.
  • Drop commits that are no longer relevant.

Example:

git checkout branch_x
git rebase -i master  

This opens a commit list in your editor where you can choose actions. It’s often used before pushing a branch to clean up “work in progress” commits and present a structured sequence of commits.

2. Standard (Non-Interactive) Rebase

This is the default git rebase <branch> workflow. It simply reapplies your commits on top of another branch without any prompts or editing steps. Think of it as moving your entire branch forward so it sits on the latest commit of the target branch. 

Example:

git checkout branch_x 
git rebase master

This takes the commits from branch_x and places them on top of the latest master commit. The result is a clean, linear history without extra merge commits.

3. Auto-Merge Rebase

During a rebase, Git will try to apply each commit automatically. If your changes don’t overlap with updates in the target branch, Git will merge them without asking. However, if a conflict arises, Git will pause the process, allowing you to resolve it manually using git rebase –continue.

This type of rebase works best when you regularly rebase your feature branch. Frequent rebasing reduces the risk of large, messy conflicts later.

Common Git Rebase Commands

Here are some of the most frequently used commands when working with git rebase:

  • git rebase master
    Reapplies the commits from your current branch on top of the latest master.
  • git rebase –continue
    Resumes the rebase after you’ve fixed merge conflicts.
  • git rebase –abort
    Stops the rebase and resets the branch back to its original state.
  • git rebase –skip
    Skips the commit that caused a conflict and continues rebasing the rest. Use cautiously, since it may drop important changes.
  • git rebase -i HEAD~3
    Starts an interactive rebase for the last three commits, letting you reorder, squash, or edit commit messages.

Configuration Options in Git Rebase

Git rebase comes with several options that let you adjust how it works:

  • –interactive or -i – Runs an interactive rebase so you can edit, squash, or reorder commits.
  • –onto <newbase> – Moves a branch onto a different base commit. Useful when you need to rebase off something other than the original parent.
  • –no-verify – Skips pre-commit and commit-msg hooks during rebase.
  • –autosquash – Automatically squashes commits that were marked with fixup! or squash!.

Undoing a Rebase

If a rebase goes wrong and you want to roll back, use:

git reset --hard <branch-name>

This resets your branch to its state before the rebase started.

Recovering Lost Commits After a Rebase

Sometimes commits may appear “lost” after a rebase. They’re usually recoverable with these steps:

  1. Check the reflog
    git reflog

This shows a history of commits, including ones that were moved or replaced.

  1. Create a new branch from the commit
    git branch <new-branch> <commit-id>
  2. Cherry-pick the lost commits
    git cherry-pick <commit-id>
  3. Resolve conflicts if needed
    git add <file>
    git rebase –continue
  4. Push the recovered branch
    git push -u origin <new-branch>

With this process, even after an upstream rebase or a mistake, your work can be restored safely.

Handling Git Rebase Conflicts

Conflicts are common when rebasing, especially if both branches changed the same parts of a file. Here’s how to deal with them.

  1. Detecting conflicts
    When a conflict occurs, Git will pause the rebase and mark the files that need attention.
  2. Resolve conflicts
    Open the conflicted file(s).
    Edit to keep the correct changes.
    Stage the fixes:
    git add <file>
    Continue the rebase:
    git rebase –continue
  1. Skip a commit
    If a specific commit isn’t needed, you can skip it and continue:
    git rebase –skip
  2. Abort the rebase
    To cancel and return to the state before rebasing:
    git rebase –abort

Note: In most cases, resolving and continuing is the right approach. Skipping or aborting should only be used if you’re sure the commit can be dropped or you want to start over.

Pushing Changes After a Rebase

When you rebase, Git rewrites commit history. That means the commits on your local branch no longer match the ones on the remote branch. If you try a normal git push, it will fail because Git thinks your branch is “behind.”

Why Push Fails

Rebase creates new commits (with new IDs), so the remote branch doesn’t recognize them as the same history.

Fixing It with –force-with-lease

Instead of overwriting blindly with git push –force, use:

git push --force-with-lease

This updates the remote branch but first checks if someone else pushed changes after your last fetch. It’s safer because it prevents you from accidentally deleting their work.

Best Practices for Git Rebase

  1. Always pull (git fetch) before pushing after a rebase.
  2. Use –force-with-lease instead of –force.
  3. Communicate with teammates before force-pushing to shared branches.
  4. Rebase local work only – don’t rewrite public history.
  5. Use interactive rebase to squash or reorder commits before pushing.
  6. Rebase often to keep your branch updated and avoid big conflicts.
  7. Check history with git log –oneline –graph after rebasing.
  8. Abort if stuck (git rebase –abort) and recover with git reflog if needed.

Git Rebase vs Merge: Which Should You Choose?

Both git merge and git rebase are used to integrate changes from one branch into another, but they handle history differently.

  • Merge: Combines the histories of two branches by creating a new merge commit. The original commit structure is preserved, which can lead to a branching history with additional merge points.
  • Rebase: Moves the commits from your branch onto the tip of another branch, rewriting commit history into a straight line. This avoids extra merge commits and produces a linear history.

Git rebase vs merge – Example:

  • Using git merge, the history shows both branches and a merge commit.
  • Using git rebase, the same commits appear as if they were created sequentially on top of the target branch.

When to use each Git rebase vs merge:

  1. Use merge when you want to preserve the exact history of how changes were integrated.
  2. Use rebase when you want a simplified, linear history that is easier to read and trace.

Table: Difference between Git rebase and merge

Context Rebase Merge
Commit History Creates a clean, linear history by replaying commits on top of another branch. Preserves the full history, including branch points, and adds a merge commit.
Workflow Ideal for updating a feature branch with the latest changes before merging. Suitable for combining work while keeping the complete development history.
Commit IDs Rewrites commit IDs because it creates new commits during replay. Keeps original commit IDs intact.
Collaboration Best for local branches that haven’t been pushed to a shared repository. Safer for shared branches since it doesn’t rewrite history.

FAQs on Git Rebase

Q1. What is the difference between git rebase and git pull --rebase?

git rebase moves your branch commits onto another branch, while git pull –rebase updates your branch by rebasing it on top of the remote branch instead of creating a merge commit.

Q2. Can I undo a git rebase?

Yes. Use git rebase –abort to stop an ongoing rebase, or git reflog with git reset –hard to recover previous commits after a rebase.

Q3. Is rebase better than merge?

Rebase creates a clean, linear history by replaying commits, while merge preserves the true history with merge commits. Use rebase for a tidy project history, and merge for transparency of all branch activity.

Q4. How to squash commits using rebase?

Run git rebase -i HEAD~n and replace pick with squash (or s) for commits you want to combine. This merges multiple commits into one.

Q5. What happens if I rebase a shared branch?

Rebasing a shared branch rewrites its commit history, which can break others’ work. Avoid rebasing public or team-shared branches.

Q6. Why developers use git rebase?

Developers use Git Rebase to create a clean and linear commit history by placing their work on top of the latest changes from another branch. This makes the project history easier to read, reduces unnecessary merge commits, and simplifies debugging. Git Rebase is often used to update feature branches before merging them into the main branch.

About the Author

Senior Cloud Computing Associate, Xebia

Rupinder is a distinguished Cloud Computing & DevOps associate with architect-level AWS, Azure, and GCP certifications. He has extensive experience in Cloud Architecture, Deployment and optimization, Cloud Security, and more. He advocates for knowledge sharing and in his free time trains and mentors working professionals who are interested in the Cloud & DevOps domain.

EPGC Cloud