1001Ferramentas
๐Ÿ”€Generators

git rebase Builder

Build git rebase commands with base, --interactive, --onto, --autosquash, --no-verify.


  

Git rebase in depth: rewriting history, interactive mode, and avoiding shared-branch disasters

git rebase is one of Git's most powerful โ€” and most misunderstood โ€” commands. Where git merge integrates two histories by creating a new merge commit, git rebase rewrites history by taking your commits and re-applying them, one by one, on top of a different base. The result is a linear, "as if you never branched" history. Linus Torvalds introduced the concept inside the original Git plumbing in 2005; the modern interactive mode that lets you squash, reorder, and edit commits was added shortly after and is now the backbone of clean-PR workflows on GitHub, GitLab, and Bitbucket.

This generator produces ready-to-run rebase commands for everyday tasks (rebasing onto main, interactive cleanup, transplanting commits with --onto, autosquashing fixups). Below you will find a deep reference on the algorithm, the interactive verbs, dialect differences between merge and rebase workflows, and recovery techniques when something goes wrong.

Anatomy of a rebase: how Git replays your commits

A rebase walks the commits unique to your branch (the ones not in the new base) in order, and for each one creates a new commit with the same tree on top of the new base. Because the parent hash changes, every replayed commit gets a brand-new SHA, even if the diff is byte-identical.

git rebase main              # replay current branch on top of main
git rebase -i HEAD~5         # interactive: edit the last 5 commits
git rebase --onto target old new   # move commits between old..new onto target
git rebase --root            # rebase from the very first commit
git rebase --continue        # after fixing a conflict
git rebase --abort           # bail out, restore original branch
git rebase --skip            # drop the current commit and continue

Interactive verbs: pick, reword, edit, squash, fixup, drop, exec

  • pick โ€” keep the commit as-is.
  • reword โ€” keep the changes but open the editor to change the commit message.
  • edit โ€” stop after applying so you can amend, split, or reorganize files.
  • squash (or s) โ€” merge this commit into the previous one and combine both messages.
  • fixup (or f) โ€” same as squash but discard this commit's message.
  • drop (or d) โ€” remove the commit entirely. Deleting the line achieves the same.
  • exec โ€” run an arbitrary shell command after the commit (great for npm test between commits).
  • reorder โ€” simply rearrange the lines in the todo list to change commit order.

Rebase vs merge: which workflow is right for you?

Merge preserves the true topology โ€” you can see which commits were authored in a feature branch and when they were integrated. The history is honest but can be noisy with merge bubbles. Rebase rewrites history into a single straight line, easier to git log --oneline and bisect, but the original branching context is lost.

In practice three philosophies dominate: GitHub flow embraces merge commits (or "squash merges" that flatten a PR into one commit); GitLab flow and the Linux kernel mailing list favour rebasing onto the latest target before merging; Conventional Commits teams typically rebase plus interactive squash so every commit in main is meaningful and atomic.

Autosquash, autostash, and rerere โ€” the power-user toggles

--autosquash teams up with commits prefixed fixup! or squash! (generated by git commit --fixup=<sha>). When you later run git rebase -i --autosquash HEAD~10 Git reorders the todo list so each fixup sits beneath its target with the correct verb already filled in โ€” no manual editing required.

--autostash automatically stashes uncommitted changes before the rebase and pops them after, so you don't have to interrupt your work-in-progress. Enable globally with git config rebase.autoStash true.

git config rerere.enabled true turns on "reuse recorded resolution" โ€” Git memorises how you resolved a conflict and replays the resolution automatically the next time the same conflict appears. Indispensable on long-running rebases and on branches that get rebased multiple times.

Shared-branch pitfalls and recovery

The golden rule: never rebase a branch that has been pushed and that other people are working from. Because rebase rewrites SHAs, the next git push requires --force (or the safer --force-with-lease), and anyone with the old commits checked out has to recover manually. The exception is your own feature branch in a PR: force-push there is fine, ideally after approvals so reviewers don't lose context.

Conflicts can appear once per replayed commit โ€” sometimes the same conflict surfaces three or four times during a single rebase. After fixing files, git add them and run git rebase --continue. Don't git commit manually mid-rebase; the rebase machinery creates the commit for you.

Recovery: Git's reflog retains every HEAD you've pointed at for 90 days by default. Lost a commit after a bad rebase? Run git reflog, find the SHA you want, and either git reset --hard <sha> to restore or git cherry-pick <sha> to bring it forward. ORIG_HEAD is automatically set to where the branch was before the rebase started โ€” git reset --hard ORIG_HEAD undoes the operation in one step.

FAQ

Can I undo a rebase? Yes. Run git reflog, locate the entry just before "rebase (start)", and git reset --hard HEAD@{N}. Within 90 days the original commits remain in the object database even though no branch points at them.

Should I rebase my pull request before merging? Depends on the team. Many shops require a rebase onto the latest main so the PR merges fast-forward; others use "squash and merge" which sidesteps the question. Force-push only after approvals so reviewers don't lose their place.

Rebase or merge โ€” which should I always use? Neither in absolute terms. Rebase for in-progress feature branches you alone work on; merge (or squash-merge) when integrating finished work into shared trunks. The worst-case is mixing strategies on the same branch.

What happens to merge commits when I rebase? By default they are flattened and rewritten as ordinary commits. Pass --rebase-merges (or -r) to preserve the merge topology โ€” useful when integrating multiple sub-branches.

How do I rebase only the last few commits without touching older history? Use git rebase -i HEAD~N where N is the count of commits to include. Git replays them on the same base, so main's integration point is untouched โ€” only your local commits change SHA.

Related Tools