Introduction
Lately, I have implemented many features in my pet project and realised that none of the created branches were merged with the master code. And, I wanted to have a clean update. I was thinking that the Git rebase is a perfect and safest solution since I am working on this project alone.
But then I stopped and asked myself: âIs it really safe? Should I even be doing this?â
If youâve ever wondered the same thing, this post is for you. Iâll explain what Git rebase actually does, when itâs brilliant, and when it can cause absolute chaos. No panic, please. Weâll figure this out together.
TL;DR
- Use
rebasefor a clean, linear history (solo work). - Use
mergefor shared branches (donât rewrite history). - Always test and use
--force-with-leasewhen pushing rebased code. git reflogcan save your day.
Note: In many newer Git repositories, the default branch is called main instead of master. The same logic applies â swap the name accordingly. I use master though :)
What is Git rebase?
Think of Git rebase as rearranging your commits to make them appear as if they were built on top of the latest code, even though they werenât originally.
Hereâs what actually happens: Git takes your feature branch commits, temporarily removes them, updates your branch to match the latest master, and then replays your commits one by one on top.
The result? - A clean, linear history without messy merge commits cluttering your timeline.
Is Git rebase safer than the merge?
Short answer: rebasing isnât âsafer,â itâs âcleaner.â
It rewrites history to make it look like you built your feature on top of the latest master. Thatâs lovely for a linear history, but you must be careful if the branch has already been pushed and others have pulled it.
In reality, both rebase and merge are safe when used correctly. Theyâre just different tools for different situations. Merge preserves the true history of what happenedâwhen branches diverged, when they came back together. Rebase creates a prettier story, but itâs a story that didnât actually happen that way.
Merge:
A---B---C feature
\ /
D---E---F master
Rebase:
A'--B'--C'
/
D---E---F master
Hereâs how to do it safely and cleanly.
What rebase does (in plain words)
Rebase vs. Merge Architectural Differences
| Strategy | Mechanism | Visual Result | Use Case |
|---|---|---|---|
| Merge | Keeps the true history and adds a âmerge commitâ that records when the divergent branches came back together. | A branching, interwoven timeline of actual development events. | Shared branches where teammates explicitly depend on preserving the existing timeline and commit IDs. |
| Rebase | Replays your feature commits sequentially as if they were originally created directly on top of the newest master. |
A straight, clean, continuous linear history without merge commits. | Solo work or isolated feature branches where a clean narrative is preferred over chronological accuracy. |
Use rebase when you want a tidy, linear history and youâre working alone or on a branch nobody else has touched. Use merge when you donât want to rewrite commits, especially on shared branches where teammates depend on the existing history.
The safe rebase workflow (recommended)
I will show you the workflow I use myself. It has saved me many times from making a mess of my repositories.
Before we start, It is good to play it safe when you do a lot of development, right? If you are very cautious or a perfectionist, you can also back up your branch before rebasing:
git branch backup/feature
1) Update local info
First, fetch the latest changes from the remote repository without merging them yet:
git fetch origin
This downloads all the new commits but doesnât change any of your local branches. Think of it as checking whatâs new without touching anything.
2) Rebase your feature onto the latest master
Now switch to your feature branch and replay your commits on top of the updated master:
git checkout feature
git rebase origin/master
-
If there are conflicts, Git will pause and let you fix them. After fixing conflicts in your files, tell Git youâre done:
git add <file(s)-you-fixed> git rebase --continue -
If you get stuck and everything feels wrong, donât panic. You can abort the entire rebase and go back to where you started:
git rebase --abort
3) Run tests locally
Make sure everything still works. Seriously, do not skip this step. I learned this the hard way when I rebased a branch and pushed it without testing, only to discover I had broken the build. Not fun.
4) Fast-forward master to include the rebased feature
Now that your feature branch is cleanly sitting on top of master, you can update master:
git checkout master
git pull --ff-only origin master
git merge --ff-only feature
git push origin master
--ff-onlyguarantees we donât create an extra merge commit. If it refuses, something is offâstop and check what happened. Maybe someone pushed to master while you were working.
Please note that âno-ff can intentionally create a merge commit even when fast-forwarding is possibleâsome teams prefer that for traceability.
5) (If you had already pushed feature)
Because rebase rewrites your feature commits by giving them new commit IDs, you must update the remote branch with force. But please, be careful here:
git checkout feature
git push --force-with-lease origin feature
- Use
--force-with-lease(not--force) to avoid overwriting someone elseâs new work. The--force-with-leaseoption checks if the remote branch is still where you expect it to be. If someone else pushed to it, it will refuse and protect their work.
6) Optional clean-up
Once your feature is merged, you can delete the branch locally and remotely:
git branch -d feature
git push origin --delete feature
This keeps your repository tidy. I like doing this because otherwise, I end up with dozens of old branches and forget what they were for.
Bonus tip
If you want to clean commits eventually (git rebase -i), you can use git rebase -i HEAD~n to squash, reorder, or edit recent commits interactively. Itâs perfect for polishing your history before merging.
When is rebase âsafeâ vs âriskyâ?
Rebase Risk Matrix
| Risk Level | Scenario | Consequence |
|---|---|---|
| â Safe | Local branches no one else has pulled; personal pet projects; isolated PR feature branches you alone own. | Clean, linear history. No impact on team members. |
| â ïž High Risk | Rebasing a shared branch that teammates have already pulled locally. | You rewrite shared commit IDs, causing catastrophic divergence and forcing teammates to manually reconcile histories. |
Rule of thumb: Donât rebase public/shared history. If you must, coordinate with the team and use --force-with-lease. Send them a message first. Maybe bring cookies :)
Actually, some teams use rebase all the time and have workflows built around it. But they coordinate carefully. If youâre new to this, start with local branches and pet projects.
Quick example (tiny, concrete)
Suppose master moved ahead by two commits while you were building feature. You have commits A and B on your feature branch. Master now has commits M1 and M2.
-
Before rebase:
master : M1---M2 (new upstream commits) feature: A---B (your two commits, branched from before M1 and M2) -
After rebase:
master : M1---M2 feature: A'---B' (same changes, new commit IDs)Notice A and B became Aâ and Bâ. They contain the same code changes you wrote, but theyâre technically new commits with different IDs and different parent commits.
-
Then fast-forward
masterto includeA'andB'without a merge commit:master : M1---M2---A'---B'
Beautiful, clean, linear history. No merge commits cluttering things up.
Handy âpanic buttonsâ
Sometimes things go wrong. It happens to everyone. Here are your escape routes:
Git Disaster Recovery Cheat Sheet
| Disaster Scenario | Recovery Command | Mechanism |
|---|---|---|
| Mid-Rebase Chaos (Stuck in endless conflict loops during an active rebase) | git rebase --abort |
Immediately cancels the active rebase process and restores your working tree to the exact state before the rebase started. |
| Catastrophic History Corruption (You completed a bad rebase or merge and ruined your branch) | git refloggit reset --hard HEAD@{n} |
reflog exposes the hidden timeline of every state your local HEAD has visited. reset --hard forces your branch back to that exact historical safety point. |
| Accidental Merge (You successfully merged the wrong branch locally) | git reset --hard ORIG_HEAD |
Automatically reverts your local branch to the state immediately preceding the last dangerous operation (like a merge). |
The reflog is like a safety net. It records everywhere your HEAD has been, allowing you to go back in time. Iâve used this to recover from disasters more times than I care to admit.
Should you use rebase here?
If youâre the only person working on feature, yesârebase â fast-forward gives you a neat history thatâs easy to follow. Youâll thank yourself later when youâre looking through the commit log trying to understand when something was introduced.
If others have already pulled your feature branch, you have two options:
- finish with a regular merge (no history rewrite), keeping everyoneâs sanity intact, or
- coordinate and use
--force-with-lease, making sure everyone knows youâre about to rewrite history.
Actually, in my pet project where Iâm working alone, I use rebase all the time. It makes the history so much cleaner. But at work, where we collaborate? Iâm much more careful.
Conclusion
Rebase is a powerful tool for keeping your Git history clean and linear, but it comes with responsibility. Use it freely on your own branches and pet projects. Use it carefully on shared work. And always remember: you can abort a rebase, check the reflog, and recover from mistakes.
The most important thing? Donât be afraid to experiment. Make a test repository and play around with rebase until you understand how it works. Break things, fix them, break them again. Thatâs how we all learned Gitâby making mistakes in safe environments.
Good luck with your rebasing adventures! If you found this helpful, or if you have questions, please let me know.
đ Further reading
- git-rebase documentation
- git-merge documentation
- git-push âforce-with-lease
- git-reflog
- Pro Git Book, Chapter 3.6 â Rewriting History
Did you like this post? Please let me know if you have any comments or suggestions.
Git posts that might be interesting for you