Clean up historyAlways fixable

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.

quick fix
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

  1. 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 1
    git rebase -i HEAD~3
    
    # change:
    #   pick a1b2c3d Big commit with three unrelated changes
    # to:
    #   edit a1b2c3d Big commit with three unrelated changes
    
  2. Undo 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 2
    git reset HEAD~
    

    Use plain reset (mixed), not --soft — you want the changes unstaged so you can pick them apart.

  3. 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 3
    git 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"
    
  4. Finish the rebase

    Continuing replays the remaining commits on top of your newly split ones. Check the result before pushing.

    step 4
    git rebase --continue
    git log --oneline -6
    
  5. If it goes wrong, abort

    At any point during the rebase you can back out completely and return to the original commit untouched.

    step 5
    git 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

git rebase -i

Reorder, squash, split, reword or drop your recent commits.

git reset

Move the current branch pointer, optionally rewriting the index and your files.

git add

Stage changes so they go into your next commit.

git commit

Record everything currently staged as a permanent snapshot.

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

← All Git Rescue guides