Elena' s AI Blog

Should you use rebase?

16 Oct 2025 / 12 minutes to read

Elena Daehnhardt


Midjourney 7.0: Clean Git history with rebase


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 rebase for a clean, linear history (solo work).
  • Use merge for shared branches (don’t rewrite history).
  • Always test and use --force-with-lease when pushing rebased code.
  • git reflog can 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)

  • Merge: keeps the true history and adds a “merge commit” that shows when branches came together. You see the actual timeline of development.
  • Rebase: replays your feature commits as if they were created on top of the newest master—no merge commit; a straight line. Your commits get new IDs because they’re technically new commits.

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-only guarantees 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-lease option 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”?

  • Safe: local branches no one else has pulled yet; PR branches you alone own; your personal pet projects where you’re the only developer.
  • ⚠️ Risky: rebasing a branch that teammates have already pulled. You’ll make their histories diverge and force them to reconcile. They will not be happy with you.

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 master to include A' and B' 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:

  • Undo an in-progress rebase:

    git rebase --abort
    

    This takes you right back to before you started the rebase. Like it never happened.

  • After a bad merge/rebase, use the reflog to find your last good state:

    git reflog          # find the last good commit (e.g., HEAD@{2})
    git reset --hard HEAD@{2}
    

    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.

  • After a merge you didn’t want:

    git reset --hard ORIG_HEAD
    

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

  1. git-rebase documentation
  2. git-merge documentation
  3. git-push —force-with-lease
  4. git-reflog
  5. 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




desktop bg dark

About Elena

Elena, a PhD in Computer Science, simplifies AI concepts and helps you use machine learning.





Citation
Elena Daehnhardt. (2025) 'Should you use rebase?', daehnhardt.com, 16 October 2025. Available at: https://daehnhardt.com/blog/2025/10/16/should-you-use-rebase/
All Posts