Git rebase vs fast forward

Greg Foster
Greg Foster
Graphite software engineer

In Git, managing branches and integrating changes from one branch into another are fundamental tasks. Two common methods for integrating changes are the "rebase" and the "fast forward" approaches. Both have distinct workflows and use cases, which can significantly affect the project history and the review process.

A fast forward occurs in Git when you merge one branch into another, and there are no divergent commits between them. In this case, the merge can simply move the branch pointer forward, effectively catching it up with the commits on the other branch without creating a new merge commit. This is the default behavior of Git when it detects that a fast forward is possible.

How fast forward works:

  • Scenario: You have a main branch and a feature branch. The feature branch has commits that the main branch does not, but there are no new commits on main since the feature branch was created.
  • Action: When you merge the feature branch into main, Git simply moves the main branch pointer forward to the end of the feature branch.
  • Result: The history remains linear, which can simplify both the history and the understanding of the project's progression.

Fast Forward Example:

Terminal
A - B - C [main]
\
D - E [feature]

After a fast forward merge:

Terminal
A - B - C - D - E [main]

Rebasing is a process to move a series of commits to a new base commit. It's useful for cleaning up your project history before merging changes. Rebase offers a way to rewrite history by transferring a branch from one base commit to another, making it seem like you created your branch from a different point in the repository's history.

How rebase works:

  • Scenario: You have a main branch and a feature branch. The feature branch is behind the main branch by several commits.
  • Action: When you rebase the feature branch onto main, Git replays each commit from the feature branch on top of the main branch in order.
  • Result: This results in a cleaner, linear history that looks as if the feature branch was started from the latest commit on main.

Rebase Example:

Terminal
A - B - C [main]
\
D - E [feature]

After rebasing feature onto main:

Terminal
A - B - C [main]
\
D - E [feature]

(Note: D' and E' are rebased commits, which are actually new commits with different SHAs.)

Fast forward merge:

  • Pro: Maintains a linear project history without extra merge commits.
  • Con: Not always possible (only works if there are no new commits on the base branch).

Rebase:

  • Pro: Also maintains a linear history and avoids merge commits, making it look as if changes were made sequentially.
  • Con: Rewrites commit history, which can be problematic for shared branches as it requires force pushing.
  • Fast Forward: Best used when you have a short-lived feature branch that needs to be merged back into a main branch, and no other changes have been made to the main branch in the meantime.
  • Rebase: Ideal for feature branches that have fallen behind the main development line and need updating. It’s particularly useful before merging long-running branches to ensure they apply cleanly on top of the base branch.

Fast Forward Merge:

Terminal
git checkout main
git merge feature --ff-only

This command will only succeed if the merge can be performed using a fast forward.

Rebase:

Terminal
git checkout feature
git rebase main

This rebase command rewrites the history of the feature branch as if it started from the latest commit on main.

For further reading see the official documentation on Git merging.

On this page
Stay unblocked. Ship faster.
Experience the new developer workflow - create, review, and merge code continuously. Get started with one command.
Get started

Give your PR workflow
an upgrade today

Stack easier | Ship smaller | Review quicker

Or install our CLI.
Product Screenshot 1
Product Screenshot 2