Git Rebase: A Guide to Rebasing Branch Commits

Git rebase is a powerful command that enables developers to adjust commit history, apply changes from one branch to another, and maintain a tidy, linear project timeline. This article describes how to rebase branch commits in Git.

The Short Answer Version

If you are already familiar with Git and need a quick reference for rebasing commands, here are the essentials:

# Reapply your branch commits on top of the latest main
$ git switch feature   ## Switch to your feature branch
$ git rebase main      ## Rebase commits onto the main branch

# Interactively rebase the last 3 commits (edit, squash, reorder)
$ git rebase -i HEAD~3

# Rebase local commits while pulling remote changes (cleaner history)
$ git pull --rebase origin main

# After rebase, push rewritten history to remote
$ git push --force-with-lease  ## Safer than --force

Understanding Git Rebase

Rebasing transfers commits from a source branch and reapplies them on top of a target branch. This results in a streamlined commit history without additional merge commits. While the commits remain functionally the same, their IDs change, because Git creates new commits based on the old ones.

Command Syntax

git rebase [OPTIONS] [UPSTREAM [BRANCH]]

  • [OPTIONS]: Define how the command behaves. Covered later in this article.
  • UPSTREAM: The branch onto which commits will be reapplied.
  • [BRANCH]: The branch whose commits are being rebased. Defaults to the current branch if omitted.

Command Usage

Switch to the branch you want to rebase:

$ git switch feature-branch

Reapply your feature branch commits on top of main:

Clean up commits interactively before rebasing:

Push your branch (if it has never been pushed before):

If you have already pushed the branch before rebasing, use force push (as the history has changed):

$ git push --force-with-lease

Note: Using --force-with-lease instead of --force ensures you don’t overwrite others’ work on the branch.

Git Rebase vs Git Merge

git rebase rewrites commit history by moving commits between branches. git merge, in contrast, generates a new commit that merges the changes of two branches, keeping history intact without modifying commit positions.

Choose merging for shared branches, and rebasing for cleaning local or feature branch history before merging.

When to Use Rebase

  • When you want a simpler, linear history.
  • When you want to avoid unnecessary merge commits.
  • When you need to reapply changes on top of the latest main branch before pushing.

Git Merge

Git Merge integrates changes from one branch into another, creating a merge commit that preserves the histories of both branches. This allows a clear record of how development progressed.

Switch to your main branch:

Merge the feature branch into main, creating a merge commit if required:

$ git merge feature-branch

Types of Git Rebase

Interactive Rebase

Interactive rebasing enables you to edit, remove, squash, or reorder commits. It’s perfect for cleaning messy commit histories before pushing to a shared repository.

Start an interactive rebase of the last three commits:

You’ll see a list like this in your editor:

pick  a1b2c3d  Add login functionality
pick  b2c3d4e  Fix login bug
pick  c3d4e5f  Update login style

You can replace pick with:

  • reword: Modify commit message
  • edit: Adjust the commit
  • squash: Combine with previous commit
  • drop: Remove the commit

Non-Interactive Rebase

This default mode replays commits on top of another branch in the same order, without allowing interactive edits. Useful for keeping a feature branch updated with the base branch.

Rebase commits on top of main:

Auto-Merge Rebase

When using --autostash, Git automatically stashes local changes before rebasing and reapplies them afterward, preventing errors from uncommitted changes.

Stash local changes, rebase onto main, and reapply stashed changes after rebase:

$ git rebase main --autostash

Common Configuration Options

Below are the frequently used configuration options for git rebase:

  • –interactive (-i): Opens an editor to manually adjust, reorder, squash, or remove commits during the rebase process.
  • –skip: Skips the current commit (usually one that triggered a conflict) and continues the rebase.
  • –continue: Proceeds with the rebase after conflicts are resolved and changes are staged.
  • –abort: Stops the rebase and resets the branch to its original state before the rebase began.
  • –autostash: Automatically stashes any uncommitted local changes before rebasing and reapplies them afterward.
  • –onto <newbase>: Rebases a range of commits onto a new base commit, typically used in advanced scenarios.

Conclusion

In this article, you explored how to rebase Git commits using both interactive and non-interactive methods, while also understanding the distinction between rebase and merge. By applying these techniques, you can maintain a cleaner commit history, reduce unnecessary merge commits, and improve collaboration workflows. For further details, consult the official Git documentation.

Source: vultr.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: