Rebase: what it is, how rebase works and working with Git

Author: IT Sectr Published: 2026-08-01 Reading time: 9 min

Rebase is a Git operation that moves commits from one branch to the tip of another, creating a linear history without unnecessary merge commits. Unlike merging, rebase rewrites history: each moved commit gets a new hash because its parent changes. According to Git documentation (2026), rebase is used to sync feature branches with the latest main state before creating a pull request. The git rebase command is one of the main tools for maintaining a clean history in projects using Git Flow.

Key Takeaways

  • Rebase — moves feature branch commits to the tip of the target branch, creating new hashes.
  • Linear history — the main advantage of rebase: no merge commits simplifies reading the change log.
  • Interactive rebase with the -i flag allows combining, renaming, and deleting commits before publishing.
  • Public branches — rebase is forbidden for branches used by other developers because it rewrites history.
  • Conflicts possible — when moving commits, Git may ask to resolve conflicts for each commit individually.

What is Rebase in Git

Rebase is a Git command that rebases the current branch onto a specified one: it takes all commits from the current branch, temporarily saves them, moves the branch pointer to the target commit, and sequentially applies the saved commits on top of it. The result — the history looks as if the developer worked directly from the latest commit of the target branch.

The basic syntax: git rebase main — while on a feature branch, this command moves all feature commits to the tip of main. Git uses a three-way merge strategy for each commit individually. If commit A is already present in the target branch (determined by hash), Git automatically skips it, avoiding duplicate changes.

Rebase also supports the onto mode for moving a subset of commits: git rebase --onto target start end — this form allows extracting a range of commits from one branch and applying them on top of another. For example, git rebase --onto main feature~3 feature moves the last three commits of the feature branch on top of main.

bash
# Switch to feature branch
git checkout feature

# Rebase feature onto main
git rebase main

# After successful rebase — history is linear
git log --oneline --graph

# Move last 3 commits to main
git rebase --onto main HEAD~3 HEAD

Rebase vs Merge: Key Differences

Rebase and merge solve the same task — combining changes from different branches — but they do it in fundamentally different ways. Merge preserves the full merge history by creating a merge commit with two parents. Rebase rewrites history, making it linear. The choice between them depends on the team's workflow and repository management rules.

The main difference is how the merge fact is recorded. Merge preserves: "at this point we merged feature into main" — this is informative for project history but clutters the log with frequent merges. Rebase shows: "feature commits were made sequentially from the latest main state" — this is clean but hides the fact that development was done in parallel.

The second difference is conflict handling. With merge, conflicts are resolved once and the solution is recorded in the merge commit. With rebase, conflicts can occur for each moved commit, each requiring separate resolution. This is more labor-intensive but allows more precise control over which changes end up in the final version.

CriterionRebaseMerge
HistoryLinear, without merge commitsNon-linear, with merge commits
Commit hashesRewritten (new)Original preserved
ConflictsFor each commit separatelyOnce in merge commit
Public branchesForbiddenAllowed
Undo commandgit rebase --abortgit merge --abort

Interactive Rebase: Commands and Flags

Interactive rebase (git rebase -i) is a mode where Git opens an editor with a list of commits and available actions for each one. The developer can rewrite history before pushing to a remote repository. This is the primary tool for maintaining clean commits in a feature branch.

Available commands in interactive mode: pick (keep commit as is), reword (change commit message), edit (stop for changes), squash (combine with previous commit, keeping both messages), fixup (combine, discarding the message), drop (delete commit). Each command is placed before the commit hash in the opened editor.

Squash and fixup are the most frequently used commands for combining commits. If a developer made 5 small fix commits during work, squash merges them into one logical commit with a meaningful message. Fixup is useful for fixing typos: changes go into the previous commit without keeping their own message.

bash
# Open editor for last 4 commits
git rebase -i HEAD~4

# Editor will show:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests

# After saving — Git performs rebase
# and opens editor for squashed commit message

# Auto-squash without opening editor
git rebase -i HEAD~4 --autosquash

The --autosquash flag automatically arranges fixup/squash for commits whose messages start with fixup! or squash!. This speeds up work if the developer pre-marks commits for later combination. The --committer-date-is-author-date flag preserves the original commit date when rebasing — useful for maintaining chronological order in history.

Resolving Conflicts During Rebase

Conflicts during rebase occur when Git cannot automatically apply a moved commit due to conflicts with changes in the target branch. Unlike merge, where the conflict is resolved once, with rebase each commit can cause a conflict, and it must be resolved sequentially for each commit from oldest to newest.

When a conflict occurs, Git pauses the rebase and reports which commit caused the issue. The developer opens the conflicting file (Git marks conflict areas with <<<<<<<, =======, >>>>>>> markers), edits it, adds it to the index (git add), and continues the rebase with git rebase --continue. If no solution is found — git rebase --abort completely cancels the rebase.

Tip: with multiple conflicts, it is more efficient to use git mergetool, which opens a visual editor for resolving conflicts. You can also skip the problematic commit (git rebase --skip), but this removes its changes from the final history, which is rarely the right decision.

bash
# Start rebase with conflict
git rebase main
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt

# Check status
git status
# both modified: file.txt

# Edit conflicted sections → git add → continue
git add file.txt
git rebase --continue

# If uncertain — abort
git rebase --abort

When Not to Rebase

The golden rule of rebase: never rebase commits that have already been pushed to a remote repository and are available to other developers. Since rebase rewrites commit hashes, colleagues will encounter conflicts when trying to sync — their local history will diverge from the rewritten remote history.

A situation where rebase is strictly forbidden: if someone has already created a branch based on your commits (for example, your colleague branched off your feature), rewriting history will break their work. In such cases, use merge. It is also not recommended to rebase right before a deadline — an error during conflict resolution may take longer than expected and block the release.

Exception: if the branch is used by only one developer (a personal feature branch, not published or published in draft mode), rebase before pushing is standard practice. After publishing and starting collaborative work — only merge. GitHub and GitLab by default offer squash merge as a compromise: it combines commits into one but does not rewrite the target branch history.

  • Public branches (main, develop, release) — rebase is completely forbidden.
  • Other people's commits — if the branch contains commits from another developer, rebase is not allowed.
  • Before release — conflict risks are higher: merge is safer a day before the deadline.
  • Branches with tags — moving a commit with a tag violates semantic versioning conventions.
  • CI/CD tied to hashes — some deployment systems identify builds by commit hash; rebase will break tracking.

Practical Workflow with Rebase

Modern teams most often use a rebase-oriented workflow combined with GitHub Flow. The process looks like this: the developer creates a feature branch from main, works in it, periodically syncs via git rebase main, and before creating a pull request performs an interactive rebase to clean up history.

After creating a PR (if new changes from main need to be pulled in), git pull --rebase main is used instead of a regular git pull. This pulls in changes without creating an unnecessary merge commit. Git pull with the --rebase flag is equivalent to git fetch + git rebase — Git first downloads new commits, then rebases local changes on top of them.

Git allows configuring rebase as the default behavior for pull: git config --global pull.rebase true. After this setting, git pull always performs rebase instead of merge. If a regular pull is needed — use git pull --no-rebase. Many teams also enable autostash: git config --global rebase.autoStash true — this automatically stashes uncommitted changes before rebase and restores them after.

Frequently Asked Questions

What does it mean to rebase commits in Git?

To rebase means to execute git rebase: move commits from the current branch to the tip of another. As a result, the history becomes linear, each commit gets a new hash, and merge commits are not created. The command is used to sync branches without unnecessary merge points in the log.

How is rebase different from merge?

Merge creates a merge commit with two parents, preserving parallel history and original hashes. Rebase rewrites history — commits get new hashes and the history becomes linear. Merge is safer for public branches, rebase provides a cleaner log.

How to do an interactive rebase?

The command git rebase -i HEAD~N opens an editor with the last N commits. For each commit you can choose an action: pick (keep), reword (rename), edit (modify), squash (combine with previous), fixup (combine without message), drop (delete). After saving, Git applies the chosen changes.

Why is rebase dangerous for public branches?

Rebase rewrites commit hashes, making history incompatible with copies of the same commits on other developers' machines. If a colleague already pulled your commits via git pull, and then you rebased them, their git push will be rejected, and git pull will create duplicate commits and conflicts.

Can rebase be undone after it is completed?

Before completion — git rebase --abort cancels completely. After completion, you can restore the previous state via git reflog — find the commit hash before the rebase and run git reset --hard to it. Reflog stores HEAD movement history for 30 days by default.

Summary

  • Rebase — an operation that moves commits to a new base, creating a linear history without merge commits.
  • Command git rebase main rebases the current branch onto main, applying commits sequentially on top.
  • Interactive mode -i allows combining (squash), renaming (reword), and deleting (drop) commits.
  • Conflicts during rebase are resolved for each commit separately, unlike merge.
  • Public branches must not be rebased — it breaks history for other developers.
  • git pull --rebase — a safe way to sync with a remote branch without a merge commit.
  • Git reflog allows recovery after a failed rebase within 30 days.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also