Split a commit into 2 commits with `git rebase`
Sean Larkin
Posted on December 5, 2022
Overview
Git is a powerful version control system that allows developers to track and manage changes to their code. One of the key features of Git is the ability to use interactive rebasing to modify the history of a branch.
Interactive rebasing allows you to edit, reorder, and split commits in a branch. This can be useful when you need to clean up your branch history, or when you want to split a commit that contains changes for multiple files into separate commits.
pnpm, yarn, npm lockfiles
Have you ever had to git rebase
in your project but consistently had merge conflicts in your pnpm/yarn/npm lockfiles? You may have heard the advice to 'always commit your lockfile in an isolated commit'.
This is because you can use the drop
command in an interactive rebase to remove the commit so you can regenerate the lockfile after your rebase.
Often times, I forget this and sometimes I end up with multiple files (including my lockfile) inside my single commit and now I cannot drop
it.
Getting Started
In this tutorial, we will show you how to split a commit during an interactive git rebase. We will use a simple example to illustrate the steps involved in splitting a commit.
To begin, let's assume that you have a branch called feature-branch
that is based on the master
branch. The feature-branch
contains three commits, X
, Y
, and Z
, as shown below:
A - B - C - D [master]
/
X - Y - Z [feature-branch]
The Y
commit in the feature-branch contains changes for both fileA
and fileB
. However, you want to split this commit into two separate commits, one for fileA
and one for fileB
.
Using git rebase -i
To do this, you need to start an interactive rebase using the git rebase -i
command. In this example, we will use the master branch as the base branch, so the command would be git rebase -i master
.
This will open an editor where you can specify the actions that you want to perform on each commit in the feature-branch. In this case, you want to split the Y
commit, so you need to replace the pick
command for commit Y
with the edit
command.
Once you save and close the editor, the rebase will start and it will stop at the Y
commit. This will allow you to make changes to the Y
commit.
Split the Commit!
To split the Y
commit, you first need to unstage the changes from the commit. This can be done using the git reset HEAD~
command. This will leave the changes in your working directory, but they will not be staged.
Next, you can use the git add
command to stage only the changes for fileA
. Then, you can use the git commit command to create a new commit with the changes for fileA
. This will create a new commit, Z
, in the feature-branch
, as shown below:
A - B - C - D [master]
/
X - Y - Z [feature-branch]
Now, you can use the git add
command to stage the remaining changes for fileB
. Then, you can use the git commit
command to create a new commit with the changes for fileB
. This will create a new commit, W
, in the feature-branch
, as shown below:
A - B - C - D [master]
/
X - Y - Z - W [feature-branch]
Tada!
Finally, you can use the git rebase --continue
command to continue the interactive rebase. This will apply the changes that you made to the Y
commit and create a new branch history with the two separate commits for fileA
and fileB
respectively!
Now anytime you have a pesky lockfile change included with other files in a commit, you can separate it out, and then drop
them during your rebases to make interactive rebase efficient and clean!
Posted on December 5, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.