NIXX/DEVv1.14.0
ArticlesFavorites
Sign In
Sign In
Articles

Welcome to our blog

A curated collection of insightful articles, practical guides, and expert tips designed to simplify your workflow

Cover image for: How to Clean Up Your Git History Before Merging (Without Losing Your Mind)
August 1, 20255 MIN READ min readBy ℵi✗✗

How to Clean Up Your Git History Before Merging (Without Losing Your Mind)

Master Git rebase and squash workflows to keep your project history clean and readable.

webdevgithubgit
ℵi✗✗

ℵi✗✗

Full-Stack Developer

Passionate about building tools and sharing knowledge with the developer community.

Was this helpful?

Popular Posts

  • NixOS vs. Arch Linux: Which One Belongs in Your Dev Setup?

    NixOS vs. Arch Linux: Which One Belongs in Your Dev Setup?

    5 MIN READ min read

  • How to Enable HTTPS on Localhost in Under 2 Minutes

    How to Enable HTTPS on Localhost in Under 2 Minutes

    3 MIN READ min read

  • Migrating from Create React App (CRA) to Vite: A Step-by-Step Guide

    Migrating from Create React App (CRA) to Vite: A Step-by-Step Guide

    4 MIN READ min read

  • Array Destructuring in PHP: A Practical Guide for Modern Developers

    Array Destructuring in PHP: A Practical Guide for Modern Developers

    5 MIN READ min read

Recommended Products

  • Apple iPad (7th Gen)

    Apple iPad (7th Gen)

    4.3
  • Fitbit Versa 4

    Fitbit Versa 4

    4.3
  • JBL Flip 6

    JBL Flip 6

    4.8
  • Dell 24 Monitor — SE2425HM Full HD

    Dell 24 Monitor — SE2425HM Full HD

    4.7

May contain affiliate links

Topics

webdev33productivity16cybersecurity12javascript11automation9guide8react7typescript7php6tutorial6freelancing5github actions5privacy5how to4Node.js4
+111 more topics →
🇺🇸USD ACCOUNTOpen a free US-based USD accountReceive & save in USD — powered by ClevaSponsoredInterserver Hosting#1 VALUEAffordable, reliable hosting from $2.50/mo99.9% uptimeSponsored

A pull request with working code and a commit history like this are two different things:

fix typo
fix broken test
actually fix it
try again
move button

The code may be correct, but the history makes it difficult for reviewers to understand what changed and why, and harder to trace regressions later with tools like git bisect. Interactive rebasing solves this: it lets you reorganize, rename, and consolidate commits before a branch merges, so the history tells a coherent story rather than documenting every false start.

This guide covers the interactive rebase workflow from start to finish, including squash, fixup, reword, and how to push the cleaned history back to a pull request safely.

What this covers:

  • Viewing commit history before cleaning up

  • Running an interactive rebase

  • Squashing, rewording, and dropping commits

  • Writing better commit messages

  • Using fixup for quick cleanup without prompts

  • Force-pushing safely with --force-with-lease


Why Commit History Matters

A clean commit history is not an aesthetic preference. It has practical consequences:

  • Reviewers can understand changes faster when commits are logical and well-described

  • git bisect works more reliably when commits represent discrete, complete changes rather than incremental fixes

  • The main branch stays readable over time, which matters when tracking down when and why a change was introduced

  • Merge conflicts are easier to resolve when the intent behind each commit is clear

Cleaning up history before merging is a low-effort step that benefits everyone who works on the codebase after the fact.


Step 1: View the Current Commit History

Before rebasing, review what needs cleaning up:

git log --oneline

This produces output like:

a1b2c3e fix layout issue
3f4g5h6 add error handling
7h8i9j0 temporary fix for test
b2c3d4f wip

The goal is to turn a sequence like this into one or two commits that clearly describe what the feature or fix actually does, with the intermediate work-in-progress commits collapsed.


Step 2: Start an Interactive Rebase

Run interactive rebase against the branch the PR targets, typically main or develop:

git rebase -i origin/main

This opens a text editor with a list of commits not yet in the target branch, ordered oldest to newest:

pick b2c3d4f wip
pick 3f4g5h6 add error handling
pick 7h8i9j0 temporary fix for test
pick a1b2c3e fix layout issue

Each line represents a commit and begins with an instruction. The default is pick, which keeps the commit unchanged. Changing the instruction controls what happens to that commit during the rebase.

The available instructions:

Instruction

Shorthand

Effect

pick

p

Keep the commit as-is

squash

s

Merge into the previous commit, combine messages

fixup

f

Merge into the previous commit, discard this message

reword

r

Keep the commit but edit its message

drop

d

Remove the commit entirely

edit

e

Pause the rebase to amend the commit


Step 3: Squash Work-in-Progress Commits

To collapse the four commits above into one, change the instructions for all but the first:

pick b2c3d4f wip
squash 3f4g5h6 add error handling
squash 7h8i9j0 temporary fix for test
reword a1b2c3e fix layout issue

Save and close the editor. Git processes the instructions in order:

  1. The three squash instructions merge those commits into b2c3d4f and open an editor to write a combined commit message

  2. The reword on the final commit opens another editor to rename it

Write a single clear commit message for the combined changes:

feat(auth): add error handling for invalid token responses

Then write a clear message for the rewarded commit:

fix(layout): correct button alignment on mobile breakpoints

The result is two commits that describe what was done, rather than four that document how it was done iteratively.


Step 4: Write Better Commit Messages

The commit message is the primary documentation for why a change was made. A well-written message is more valuable than a comment in the code, because it is preserved in the repository history with the exact context of when and why it was written.

A useful format is Conventional Commits:

type(scope): short description

Optional longer explanation of what changed and why.

Common types: feat, fix, refactor, docs, test, chore.

The short description should complete the sentence "This commit will..." without including the words "this commit will". Keep it under 72 characters so it displays cleanly in git log --oneline output.


Step 5: Use fixup for Quick Cleanup

When squashing commits where the intermediate messages are not worth preserving, fixup is more efficient than squash. It merges the commit into the previous one without opening an editor for the combined message.

pick 3f4g5h6 add error handling
fixup 7h8i9j0 temporary fix for test
fixup b2c3d4f wip

For a more automated workflow, commit work-in-progress changes with the --fixup flag while working:

git commit --fixup 3f4g5h6

This creates a commit prefixed with fixup! add error handling. When running the interactive rebase, pass --autosquash to automatically position and mark these fixup commits correctly:

git rebase -i --autosquash origin/main

This removes the manual step of editing the instruction list when the fixups are already tagged.


Step 6: Force-Push Safely

After rebasing, the local branch history has diverged from the remote branch. A regular push will be rejected. Push with --force-with-lease:

git push --force-with-lease

The --force-with-lease flag checks that no new commits have been added to the remote branch since the last fetch before overwriting it. If another contributor has pushed to the branch in the meantime, the push is rejected rather than overwriting their work. This is a meaningful safety guarantee that --force does not provide.

After the push, the pull request on GitHub or GitLab will reflect the updated, clean commit history.


Common Issues and Fixes

Rebase conflicts: If a conflict occurs during the rebase, Git pauses and marks the conflicting files. Resolve the conflicts manually, stage the resolved files with git add, and continue with git rebase --continue. To abandon the rebase entirely and return to the original state, run git rebase --abort.

Accidentally dropped a commit: The commit is not lost. Run git reflog to find the commit hash and use git cherry-pick <hash> to restore it.

Interactive rebase opens in the wrong editor: Set the preferred editor with git config --global core.editor "code --wait" for VS Code or git config --global core.editor "nano" for Nano.


Key Takeaways

  • git rebase -i origin/main opens the interactive rebase editor with all commits not yet in the target branch.

  • squash merges a commit into the previous one and combines their messages; fixup does the same but discards the commit's message without prompting.

  • reword keeps a commit's changes but opens an editor to rename the message.

  • drop removes a commit entirely. Use git reflog to recover it if needed.

  • git push --force-with-lease overwrites the remote branch only if no new commits have been added since the last fetch, which prevents accidentally overwriting a collaborator's work.

  • The --autosquash flag combined with git commit --fixup automates fixup positioning during the rebase.


Conclusion

Interactive rebasing is one of the higher-leverage Git skills available. The commands are simple once the mental model is clear: the interactive editor is a list of instructions Git executes in order, and changing those instructions before saving controls exactly what the history looks like.

The workflow described here, squash working commits into logical units, write clear messages, and push with --force-with-lease, produces pull requests that are easier to review and a main branch history that is easier to work with over the long term.


Have a Git history cleanup approach that works well for your team? Share it in the comments.

Topics
webdevgithubgit

Discussion

Join the discussion

Sign in to share your thoughts and engage with the community.

Sign In
Loading comments…

Continue Reading

More Articles

View all
Cover image for: AI for DevOps: Tools That Are Already Changing the Game
Jun 17, 20256 MIN READ min read

AI for DevOps: Tools That Are Already Changing the Game

How artificial intelligence is transforming CI/CD pipelines, monitoring, and incident response—today.

Cover image for: The 3-Device Rule: How to Simplify Your Digital Life and Stop Overbuying Tech
Aug 5, 20255 MIN READ min read

The 3-Device Rule: How to Simplify Your Digital Life and Stop Overbuying Tech

Tired of juggling too many devices? Learn the 3-device rule that helps you streamline your digital life, reduce clutter, and focus on what really matters.

Cover image for: What Is Identity Theft (and How to Protect Yourself Online)
Nov 17, 20256 MIN READ min read

What Is Identity Theft (and How to Protect Yourself Online)

Identity theft can happen to anyone — often without you even realizing it. Learn what it means, how it happens, and the smart steps you can take today to keep your personal information safe online.

Cover image for: React Authentication with JWT: A Step-by-Step Guide
Oct 17, 20257 MIN READ min read

React Authentication with JWT: A Step-by-Step Guide

Learn how to implement secure JWT authentication in React. From login to route protection and API calls, this guide covers everything you need to know.

|Made with · © 2026|TermsPrivacy
AboutBlogContact

Free, open-source tools for developers and creators · Community driven