Clean up feature-branch commits with TortoiseGit interactive rebase
Squash, reorder, or drop work-in-progress commits before pushing, then verify the rewritten history and recover with git reflog if needed.
31 Jul 2025, 00:58 UTC

The useful answer
If your feature branch contains several \"work in progress\" commits, TortoiseGit's interactive rebase lets you combine, reorder, edit, or drop them before you push to a shared remote. The result is a cleaner commit history, but the operation rewrites commit hashes, so you should only rebase branches your team has not already pulled, or coordinate a force-push with --force-with-lease.
How the interactive rebase works in TortoiseGit
TortoiseGit is a Windows shell extension for Git. Interactive rebase opens a dialog that lists the commits between a chosen upstream and the current HEAD, which is the latest commit on your branch. You can drag commits to reorder them, change messages inline, and set flags such as squash, fixup, or drop. When you start the rebase, TortoiseGit invokes the installed Git binary and builds a temporary rebase state under the repository's .git directory. If a commit cannot be applied cleanly, the process pauses for conflict resolution.
Worked configuration: squashing WIP commits
This example assumes a local feature branch named feature/login-fix based on main, with several small commits you want to collapse into one before sharing.
- In Windows Explorer, open the local repository folder.
- Right-click the folder, choose TortoiseGit, then Rebase\u2026.
- In the Rebase dialog, set Upstream to
main, or the branch your feature was branched from. - Check Interactive.
- Start the rebase. TortoiseGit lists the commits reachable from
feature/login-fixbut not frommain. - In the rebase plan, leave the first commit as
pick. Change later commits you want to absorb into the first one tosquash, which combines changes and messages, orfixup, which combines changes and discards the message. Drag rows to reorder if needed. - Execute the plan. If Git reports a conflict, TortoiseGit pauses. Resolve the conflicted files, mark them resolved, then continue the rebase from the TortoiseGit dialog or with
git rebase --continuein Git Bash.
Run commands in Git Bash or PowerShell inside the repository root. You need write access to the local repository. Pushing the rewritten branch requires write permission on the remote.
# Check current branch and recent commits
git branch --show-current
git log --oneline main..HEAD
# After the rebase completes, confirm the new history
git log --oneline --graph
# Confirm no interrupted rebase state remains
ls .git/rebase-merge 2>/dev/null || echo \"no rebase-merge directory\"
ls .git/rebase-apply 2>/dev/null || echo \"no rebase-apply directory\"
Expected check: git log --oneline --graph should show fewer commits than before, with the squashed changes combined into the selected commit. The .git/rebase-merge/ or .git/rebase-apply/ directories should be absent or empty; leftover files indicate an interrupted rebase.
Pushing the rewritten branch
Because interactive rebase creates new commit hashes, a normal git push will be rejected if the remote already contains the old commits. Use:
git push origin feature/login-fix --force-with-lease
--force-with-lease is safer than --force because it aborts if the remote branch has moved since you last fetched, reducing the risk of overwriting a teammate's new commits.
Limits and common mistakes
- Do not rebase branches others have pulled. Rewriting shared history forces collaborators to recover their local copies, which can cause confusion and lost work.
- Do not close the dialog without continuing. If the rebase stops on a conflict and you abort or close the UI without resolving and continuing, the repository can remain in a mid-rebase state.
- Do not use --force without --force-with-lease. A blind force-push can overwrite remote commits you have not seen.
- Git version matters. The dialog depends on the Git binary bundled with or configured for TortoiseGit. Older Git versions may handle interactive rebase differently or lack expected flags.
- Squashing is not merging. Interactive rebase replays commits; it does not preserve merge commit structure in the same way a merge does.
Verification and rollback
Interactive rebase changes repository state. If the result is wrong, the original commits are usually still recoverable through the reflog, which records recent movements of HEAD and branch references:
# View recent HEAD movements to find the pre-rebase commit
git reflog
# Reset to the pre-rebase state if needed, using the hash from reflog
git reset --hard <pre-rebase-commit-hash>
Use git reset --hard only after confirming the reflog hash, because it discards uncommitted local changes. After recovery, verify with git log --oneline --graph that the branch matches the expected pre-rebase history.
Practical decision checklist
| Condition | Recommended action |
|---|---|
| Feature branch not yet pushed | Rebase locally, then push normally. |
| Feature branch pushed, no teammates using it | Rebase and push with --force-with-lease. |
| Feature branch pulled by teammates | Avoid rebase; create a new fix commit or coordinate before rewriting. |
| Rebase stops on conflict | Resolve files, mark resolved, continue; do not close the dialog and walk away. |
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.