Join us on Facebook!
— Written by Triangles on August 09, 2021 • updated on September 06, 2021 • ID 92 —
A quick and easy way powered by git rebase.
Imagine you are working with multiple files in a Git-managed project. At some point you create a commit that include, say, changes to files a.txt
, b.txt
and c.txt
. Then, hours and many commits later, you realize that changes done to b.txt
should not be part of that commit. Maybe you want to move the changes done to b.txt
to another commit, in order to make your history clearer. In this quick tutorial I want to show you how to split a commit into multiple parts the easy way.
The first thing to do is to look at your commits history and pick a commit older than the one you want to split. Say for example that this is your history (as shown with git log --oneline
):
527247a (HEAD -> master) Add support for videos
06be701 Optimize memory allocation
85a90cf New rendering engine <--- the commit you want to split
ddb5c99 Update graphics
af1bcb2 Update documentation
...
and commit 85a90cf New rendering engine
is the one you want to split. Since commit af1bcb2 Update documentation
is older, copy its hash.
I'm going to use the interactive rebase for this step. Invoke it with
git rebase -i <your-previously-copied-hash>
for example
git rebase -i af1bcb2
This command will open up your text editor of choice with a list of all the commits starting from (but excluding) the one you passed in. Note that it might be confusing at first, since they are displayed in a reverse order, where the older commit is on top. I've added --- older commit
and --- newer commit
in the snippet below to make it clear, you won't find those notes in the editor:
pick ddb5c99 Update graphics --- older commit
pick 85a90cf New rendering engine
pick 06be701 Optimize memory allocation
pick 527247a Add support for videos --- newer commit
[... notes here ...]
In the [... notes here ...]
part you will find instructions on what you can do in this page: we need the edit
command to manipulate our commit. Find the commit you want to split in the list and change the pick
word into edit
(or e
in short). Your commit list in the editor should now look like this:
pick ddb5c99 Update graphics
edit 85a90cf New rendering engine
pick 06be701 Optimize memory allocation
pick 527247a Add support for videos
[... notes here ...]
Save the file and exit the editor. The rebase procedure has begun.
You are now editing commit 85a90cf New rendering engine
. Let's undo it:
git reset HEAD~1
Now all the changes done in that commit are unstaged and need to be committed again. This is the step where you create new smaller commits, or in other words where you split the original one. Commit the pieces individually in the usual way (git commit ...
), producing as many commits as you need.
When you are done with your surgery, invoke
git rebase --continue
to conclude the rebase. Now your history contains new, more granular commits. You can start over again instead with git rebase --abort
in case something goes wrong.
Keep in mind that now you have changed your local commit history, so it might require a force push to remote. Be careful when doing that on branches other people are working on.
Git documentation — 7.6 Git Tools - Rewriting History
Git documentation — git-reset
Scornful — Break a previous commit into multiple commits