When you push a massive change into version control, you often realize too late that it contains three distinct features and a bug fix. Keeping an oversized commit breaks the clean history your team relies on. Learning how to execute a proper git commit split saves your code review process and keeps your project history readable.
Unlike making clean commits from scratch, breaking up an already recorded commit requires rewriting history using an interactive rebase. Whether you're cleaning up a rushed end-of-day coding session or separating unrelated bug fixes, mastering this workflow prevents merge conflicts and gives reviewers a clear narrative of your work.
Preparing Your Working Directory
Before you touch any history, your working directory must be completely clean. Running commands like git status should yield no uncommitted modifications or untracked files that might interfere with the rebase state.
Next, inspect your recent history to find the exact hash of the commit you want to alter. Run: Further journalism by Bloomberg highlights comparable perspectives on this issue.
git log --oneline
Identify the parent hash of the target commit. If the target commit is three steps back, you will initiate an interactive rebase targeting that depth. Always verify your branch status before proceeding so you don't accidentally overwrite active work in progress.
Launching the Interactive Rebase
To modify a commit buried in your local history, start an interactive rebase session. If the target change is among your last three commits, execute:
git rebase -i HEAD~3
Your default terminal text editor will open a list of recent commits in reverse chronological order. Find the specific commit you want to break apart. By default, each line starts with the word pick.
Change pick to edit next to your target commit. Save and close the editor file. Git will apply the preceding commits and then pause precisely at your chosen commit, giving you control over its contents.
Resetting and Reslicing the Commit
Once Git pauses at the target commit, you need to undo the commit while keeping all your modified code safely in your working directory. Run the soft reset command:
git reset HEAD^
At this stage, your files contain all the changes from the original oversized commit, but they are completely unstaged. Now you can build new, logical commits one piece at a time.
- Selectively stage the first logical group of changes using:
Alternatively, use interactive patching (git add <specific-file-or-path>git add -p) to pick specific code hunks within individual files. - Record your first new, focused commit:
git commit -m "Refactor authentication module helpers" - Repeat the staging and committing process for the remaining changes until your working directory is clear.
Completing the Rebase Sequence
After you have turned your single oversized commit into several clean, granular units, you must resume the rebase process. Tell Git to continue through any remaining steps:
git rebase --continue
If you encounter any merge conflicts during this phase, resolve them in your files, stage the fixes, and run git rebase --continue again. Once finished, check your new project timeline:
git log --oneline
Your history will now display separate, descriptive entries for each logical change instead of one vague block of code. You can read more about version control best practices directly in the Git Documentation.
Handling Shared and Pushed History
Splitting a commit rewrites local project history, which changes commit hashes. If you've already pushed the original unsplit commit to a remote repository shared with your team, you face a common collaborative hurdle.
If other developers have already pulled that commit, rewriting history will cause merge conflicts for them. Coordinate with your team before running a forced push (git push --force-with-lease). If you are working on a private feature branch where you are the sole contributor, a forced push is safe after completing your local rebase.
Frequently Asked Questions
Can I split a commit without using an interactive rebase?
Yes. If the commit you want to split is your most recent local commit (HEAD), you can run git reset HEAD^ immediately without opening an interactive rebase session, then stage and commit your changes in smaller batches.
What happens if I make a mistake during the split?
You can abort the active rebase at any time and return your repository to its original state by running git rebase --abort.
How small should individual commits be?
Aim for atomic commits. Each commit should represent a single logical change that compiles successfully and addresses one specific objective, making debugging via git bisect much faster.