Split one big commit into several smaller ones
How do I break a large commit into multiple commits?
Short answer
Mark the commit as edit in git rebase -i, then run git reset HEAD~ to turn it back into unstaged changes. Stage the pieces one at a time with git add -p, commit each, and finish with git rebase --continue.
git rebase -i HEAD~3
# mark the commit as 'edit', then:
git reset HEAD~
git add -p
Unpack a commit back into staged pieces you can recommit separately
Does this match your situation?
- One commit contains several unrelated changes.
- A reviewer asked you to separate a refactor from a behaviour change.
- You want an atomic history where each commit does exactly one thing.
Step-by-step fix
Start an interactive rebase that includes the commit
Reach back far enough to include the commit you want to split, then change its action from pick to edit so the rebase pauses there.
step 1git rebase -i HEAD~3 # change: # pick a1b2c3d Big commit with three unrelated changes # to: # edit a1b2c3d Big commit with three unrelated changesUndo the commit but keep its changes
When the rebase stops, you're sitting on the commit. Resetting one step back removes it while leaving all its changes in your working directory, ready to be re-divided.
step 2git reset HEAD~Use plain reset (mixed), not --soft — you want the changes unstaged so you can pick them apart.
Stage and commit the pieces one at a time
git add -p walks you through each hunk and asks whether to stage it, so you can pull a single logical change out of a file that contains several. Commit, then repeat for the next piece.
step 3git add -p src/inventory.ts git commit -m "Add inventory grid" git add -p src/save.ts git commit -m "Persist inventory to save file" git add . git commit -m "Update tests"Finish the rebase
Continuing replays the remaining commits on top of your newly split ones. Check the result before pushing.
step 4git rebase --continue git log --oneline -6If it goes wrong, abort
At any point during the rebase you can back out completely and return to the original commit untouched.
step 5git rebase --abort
Why this works
Interactive rebase replays commits one at a time, and edit simply tells it to stop after applying a particular one and hand control back to you. At that moment your branch is in an ordinary state — a normal HEAD with a normal working tree — so ordinary commands work. Resetting one step back converts the commit into plain uncommitted changes, and you can build any number of commits from them before continuing. The rebase then carries on replaying the rest of the history on top of whatever you produced.
How to stop it happening again
- Stage with git add -p from the start so commits stay focused.
- Commit as soon as one logical change is complete, rather than at the end of the day.
- If a change grows beyond one concern, commit the finished part before starting the next.
Commands used in this guide
Still stuck?
Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
How do I split a commit into two in Git?
Run git rebase -i and mark the commit as edit. When the rebase pauses, run git reset HEAD~ to turn it back into uncommitted changes, stage the first half with git add -p and commit, stage the rest and commit, then git rebase --continue.
What does git add -p do?
It walks you through the diff hunk by hunk asking whether to stage each one, and can split hunks further with the s key or let you edit them by hand with e. It's the tool that makes splitting a commit practical when the changes live in the same file.
Can I split the very first commit in a repository?
Yes, with git rebase -i --root, which includes the initial commit in the rebase so you can mark it edit like any other.
Related rescue guides
How do I combine multiple commits into a single commit?
git rebase -i HEAD~n opens an editor where you mark commits as squash or fixup to fold them into the one above. For a quick all-in-one collapse, git reset --soft HEAD~n followed by a fresh commit achieves the same result with no editor at all.
Read the fix →Always fixableHow do I edit a Git commit message?
For the most recent commit, git commit --amend -m "new message" replaces it. For older commits, git rebase -i lets you mark any of them as reword. Both rewrite history, so if the commit is already pushed you'll need git push --force-with-lease and a word to your team.
Read the fix →Always fixableHow do I undo git add without losing my changes?
git restore --staged <file> removes a file from the staging area and leaves your edits completely untouched. The older equivalent is git reset HEAD <file>. Neither one touches the contents of your file, so this is a zero-risk operation.
Read the fix →Always fixableHow do I undo the last commit but keep my work?
git reset --soft HEAD~1 removes the commit and leaves every change staged, ready to recommit. Use --mixed (the default) if you also want the changes unstaged, and only use --hard if you genuinely want the work destroyed. If the commit is already pushed, revert it instead of resetting.
Read the fix →