Claude Code Git Rebase Interactive (2026)
Git rebase interactive is one of the most powerful tools in a developer’s arsenal for maintaining clean commit history. When combined with Claude Code skills, it becomes even more productive. This guide covers practical workflows, skill combinations, and automation patterns that will transform how you manage your git history.
Understanding Git Rebase Interactive
The git rebase -i command lets you modify commits in your history before pushing to a shared branch. You can reorder commits, squash multiple commits into one, edit commit messages, or drop unnecessary commits entirely. This creates a linear, readable history that makes code reviews and bug tracking significantly easier.
Start an interactive rebase with:
git rebase -i HEAD~n
Replace n with the number of commits you want to review. This opens your default editor with a list of commits and available commands.
How Rebase Differs from Merge
Developers often ask whether to use rebase or merge. Both integrate changes from one branch into another, but they produce different histories.
| Aspect | git merge | git rebase |
|---|---|---|
| History shape | Non-linear, preserves branch topology | Linear, as if commits happened sequentially |
| Commit SHAs | Original SHAs preserved | New SHAs created for rebased commits |
| Conflict resolution | Once, at merge point | once per commit |
| Best for | Long-lived integration branches | Feature branches before PR merge |
| Risk | Safe on shared branches | Never rebase shared/public branches |
A general rule: rebase your local feature branch before submitting a pull request, but use merge (or a squash-merge) once that PR lands on the main branch.
Common Rebase Operations
The interactive rebase editor offers several actions for each commit:
- pick. Use the commit as-is
- reword. Change the commit message without altering the diff
- edit. Stop at this commit so you can amend it or split it
- squash. Combine with the previous commit, merging messages
- fixup. Combine with the previous commit, discarding this message
- drop. Remove the commit entirely
- exec. Run a shell command between commits
For example, to squash the last three commits into one:
git rebase -i HEAD~3
In the editor, mark the second and third commits with squash or s:
pick abc1234 Add user authentication
squash def5678 Fix typo in auth module
squash ghi9012 Update auth tests
Save and close the editor. Git opens another prompt for your new commit message, pre-filled with all three original messages so you can craft a clean combined message.
Using fixup vs squash
fixup is a faster version of squash when you want to absorb small correction commits without polluting the combined message. This is common for commits like “fix lint”, “address review feedback”, or “WIP”:
pick a1b2c3d Implement OAuth2 login flow
fixup e4f5g6h Fix missing null check in token refresh
fixup h7i8j9k Address PR review comments
The result is a single clean commit with only the first message. Use squash when you want to preserve and merge the commit messages; use fixup to silently absorb the smaller commits.
Claude Code Integration
While Claude Code doesn’t have a dedicated /git-rebase skill, you can use other skills to enhance your rebase workflow. The /supermemory skill stores your preferred commit message patterns, and the /tdd skill ensures your commits include appropriate test coverage.
Using /supermemory for Commit Patterns
Activate supermemory to store your team’s commit conventions:
/supermemory
Remember these commit message patterns: feature/FEATURE-NAME, fix/BUG-NAME, refactor/DESCRIPTION, docs/UPDATE
When you rebase and need to write good commit messages, Claude remembers your patterns and suggests compliant messages.
You can take this further by storing your full conventional commits specification:
/supermemory
Our commit convention follows Conventional Commits:
- feat: a new feature
- fix: a bug fix
- docs: documentation only changes
- style: formatting, missing semicolons (no logic change)
- refactor: code change that neither fixes a bug nor adds a feature
- test: adding or correcting tests
- chore: changes to build process or auxiliary tools
Scope is optional but encouraged: feat(auth): add OAuth2 support
Breaking changes use ! suffix: feat(api)!: remove deprecated endpoint
With this stored, ask Claude: “Suggest conventional commit messages for these changes: [paste diff]” and receive correctly formatted suggestions you can use directly during rebase rewording.
Using /tdd Before Rebasing
Before squashing commits, verify that your changes still pass tests:
/tdd
Run the test suite for the changes in the last 3 commits to ensure nothing broke
This prevents accidentally combining commits that introduce bugs into a single “working” commit.
A more targeted approach is to run tests at each commit during the rebase itself using the exec command:
pick a1b2c3d Initial feature implementation
exec npm test
pick e5f6g7h Add user input validation
exec npm test
pick i9j0k1l Fix linting errors
exec npm test
If any exec step fails, git pauses the rebase so you can fix the problem before continuing. This gives you confidence that your final linear history is fully green at every commit.
Practical Workflow Examples
Cleaning Up Feature Branches
When your feature branch is ready for merge, clean the history before opening the pull request:
First, fetch latest changes
git fetch origin
Rebase onto the latest main
git rebase origin/main
Then clean up your commits interactively
git rebase -i $(git merge-base HEAD origin/main)
Using git merge-base instead of a hardcoded HEAD~n is more reliable, it automatically finds the point where your branch diverged from main, regardless of how many commits you have.
Your editor shows commits like:
pick a1b2c3d Initial feature implementation
pick e5f6g7h Add user input validation
pick i9j0k1l Fix linting errors
pick m2n3o4p Update documentation
pick q5r6s7t Fix typo in variable name
For a clean history, squash the fixes and updates into meaningful commits:
pick a1b2c3d Initial feature implementation
pick e5f6g7h Add user input validation
fixup i9j0k1l Fix linting errors
pick m2n3o4p Update documentation
fixup q5r6s7t Fix typo in variable name
The result: a logical progression from implementation through validation to documentation, three commits instead of five, each telling a clear story.
Splitting Large Commits
Sometimes a commit does too much. A common scenario is a developer who works on two unrelated fixes in the same sitting and commits them together. Split it during rebase:
edit a1b2c3d Fix authentication and update logging config
Git stops at that commit. Then use git reset HEAD~ to unstage the changes while keeping them in your working directory:
git reset HEAD~
Now stage only the auth-related files
git add src/auth.js src/auth.test.js
git commit -m "Fix race condition in token refresh"
Then stage the logging changes
git add config/logging.js
git commit -m "Update log rotation config for production"
Continue the rebase
git rebase --continue
You have turned one ambiguous commit into two focused, reviewable commits.
Reordering Commits for Logical Flow
Sometimes commits exist in the order you wrote them, not the order that makes the most sense for a reviewer. Reorder them by simply changing the line order in the rebase editor:
Before reordering:
pick a1b2c3d Add feature flag infrastructure
pick e5f6g7h Implement new checkout flow
pick i9j0k1l Add feature flag for checkout flow
pick m2n3o4p Write checkout flow tests
After reordering to group related changes:
pick a1b2c3d Add feature flag infrastructure
pick i9j0k1l Add feature flag for checkout flow
pick e5f6g7h Implement new checkout flow
pick m2n3o4p Write checkout flow tests
Be careful when reordering: git will apply conflicts if the commits touch overlapping lines. The /tdd skill helps verify correctness after a reorder.
Combining with the frontend-design Skill
When working on UI components, use /frontend-design to scaffold code, then rebase to organize:
/frontend-design
Create a login form component with email and password fields, validation, and accessible error messaging
After generating the component and tests across multiple saves and iterations, use interactive rebase to clean up the multiple commits into a single “Add login form component” commit with a clean, professional history.
Automating Rebase Workflows
For repetitive tasks, create shell functions in your ~/.zshrc or ~/.bashrc:
Quick squash of last n commits
function gsquash() {
git rebase -i HEAD~$1
}
Interactive rebase from main (finds the branch point automatically)
function grebase() {
git rebase -i $(git merge-base HEAD origin/main)
}
Safe force push after rebase
function gpushf() {
git push --force-with-lease origin $(git branch --show-current)
}
Show commits since branching from main
function glog-branch() {
git log --oneline $(git merge-base HEAD origin/main)..HEAD
}
Use these in your terminal while Claude Code handles the reasoning:
/tdd
Review the changes in my current branch and suggest how to organize them into logical commits
Claude analyzes your changes and recommends a rebase strategy. You then execute with your aliases.
Git Aliases for Rebase Operations
Git’s own alias system can complement your shell functions:
git config --global alias.ri 'rebase -i'
git config --global alias.rc 'rebase --continue'
git config --global alias.ra 'rebase --abort'
git config --global alias.rs 'rebase --skip'
git config --global alias.fpush 'push --force-with-lease'
git config --global alias.branch-log 'log --oneline @{upstream}..'
With these aliases: git ri HEAD~5 starts an interactive rebase of the last five commits, git rc continues after resolving a conflict, and git fpush safely force-pushes after rebase.
Handling Rebase Conflicts
Rebase conflicts are inevitable when rebasing onto a branch that has diverged significantly. Unlike merge conflicts (which you resolve once), rebase conflicts can occur at each commit being replayed. Here is a systematic approach:
- Identify conflicts: Git lists conflicting files with
git status - Open each file: Look for conflict markers (
<<<<<<<,=======,>>>>>>>) - Understand context: The
<<<<<<< HEADsection is the target branch state; the>>>>>>> commit-hashsection is your commit’s changes - Resolve manually: Edit each file, keep the correct combination of changes, remove conflict markers
- Stage resolved files:
git add <resolved-file> - Continue:
git rebase --continue
If you get into a bad state and want to start over:
git rebase --abort
This returns your branch to exactly the state it was before you started the rebase.
Using a Merge Tool
Configure a visual merge tool to make conflict resolution easier:
Use VS Code as merge tool
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
Use vimdiff
git config --global merge.tool vimdiff
Open the merge tool for conflicts
git mergetool
Use the /tdd skill to verify your resolution doesn’t break existing functionality:
/tdd
Check if the conflict resolution in src/auth.js maintains the expected behavior for the authentication module
When to Use –rebase-merges
If your branch contains merge commits (e.g., you merged main into your feature branch mid-development), standard git rebase -i will flatten those merges. Use --rebase-merges to preserve the merge structure:
git rebase -i --rebase-merges origin/main
This is less common but essential when you have intentional merge commits that you want to keep in the rebased history.
Best Practices
- Rebase local branches only. Never rebase commits that have been pushed to a shared branch others are working from
- Use force-with-lease. When forcing push after rebase:
git push --force-with-leasechecks that no one else has pushed since you last fetched, preventing accidental overwrites - Keep commits atomic. Each commit should do one thing and do it completely, so it can be cherry-picked, reverted, or bisected independently
- Write clear messages. Start with a verb in the imperative mood: “Add”, “Fix”, “Update”, “Remove”, “Refactor”
- Communicate with teammates. If you must rebase a branch others are tracking, coordinate in advance and have them reset their local copies after your force push
- Rebase early and often. Rebasing onto a slightly diverged main is much easier than rebasing onto a main that has six months of changes
Commit Message Best Practices
A good commit message has a subject line under 72 characters and an optional body that explains the “why”:
feat(auth): add refresh token rotation
Previously, refresh tokens were long-lived and never rotated, creating
a security risk if a token was leaked. This change rotates the refresh
token on every use and invalidates the old token immediately.
Closes #412
Claude Code can audit your commit messages during a rebase session:
claude "Read the output of 'git log --oneline HEAD~10..HEAD' and tell me which commit messages do not follow conventional commits format or are too vague to be useful in a changelog."
Generating Changelogs with /pdf
After cleaning your history, generate a changelog using the /pdf skill:
/pdf
Generate a changelog PDF from the commits in the release branch since v1.0.0
This extracts your clean commit messages into a formatted document for stakeholders. You can also ask Claude Code directly to build a Markdown changelog from your git log:
claude "Run 'git log v1.0.0..HEAD --pretty=format:\"%h %s\"' and organize the output into a CHANGELOG.md grouped by feat, fix, docs, and chore commit types. Use Keep a Changelog format."
Git Bisect: The Rebase Companion
Clean commit history pays the biggest dividends when using git bisect to track down a regression. Because each commit is atomic and tested, bisect can automatically find which commit introduced a bug:
git bisect start
git bisect bad HEAD # Current HEAD is broken
git bisect good v1.2.0 # Last known good version
Git checks out a middle commit; run your test
npm test
git bisect good # or: git bisect bad
Repeat until git identifies the culprit commit
git bisect reset
Ask Claude Code to help write a bisect test script:
claude "Write a bash script that bisect can use to automatically test whether the login feature works. It should run our test suite and return exit code 0 for good, 1 for bad. Save it as scripts/bisect-test.sh."
Then run fully automated bisect:
git bisect start HEAD v1.2.0
git bisect run ./scripts/bisect-test.sh
This only works because your rebased history has clean, atomic, always-green commits at every point.
Conclusion
The git rebase interactive workflow becomes significantly more productive when combined with Claude Code skills. Use /supermemory to remember your commit patterns, /tdd to verify changes before squashing, and /frontend-design to generate clean component commits. Your shell aliases and git aliases handle execution while Claude Code provides intelligent guidance on how to organize your changes.
A clean git history isn’t just aesthetic, it’s a communication tool that helps teams understand context, trace bugs with bisect, generate accurate changelogs, and ship better software. Investing time in learning interactive rebase pays compound returns every time someone reads your commit history six months from now and immediately understands what happened and why.
Related Reading
- Best Claude Skills for Developers in 2026. Full developer skill stack including tdd and supermemory
- Claude Skills Auto Invocation: How It Works. How skills activate automatically
- Automated Testing Pipeline with Claude TDD Skill. Build testing into your workflow
- Claude Code Integration Testing Strategy Guide. Comprehensive testing strategies
Built by theluckystrike. More at zovo.one
Find the right skill → Browse 155+ skills in our Skill Finder.
See Also
Try it: Paste your error into our Error Diagnostic for an instant fix.