Splitting a Commit in Git

In this blog post, we will learn how to split a commit in Git.

Step 1: Clone this repo on your local machine.

git clone git@github.com:pawanpoudel/split_dudeism.git

Step 2: cd into split_dudeism directory and git log it.

cd split_dudeism
git log --oneline
923c105 Go ahead, read me...
4ea45e4 Split me. I am too big...
a258b8e Are you going to a lebowski fest?
e61add7 Dudeism - this is where it all starts

Step 3: Let’s split the second commit from top into three. We will give that commit a name first.

git branch split_target 4ea45e4

Step 4: Rebase interactively with split_target‘s immediate parent as the base commit.

git rebase -i split_target~

We are using the ~ (tilde) here to get to split_target’s parent. You might have seen the ^ (caret) being used to get to a parent in other examples. There is a subtle difference between these two. I think ~ is a better choice for our example. Plus if you are using zsh as your shell, you don’t need to escape ~.

There should only be two commits in your interactive rebase window.

pick 4ea45e4 Split me. I am too big...
pick 923c105 Go ahead, read me...

# Rebase a258b8e..923c105 onto a258b8e
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
...

Step 5: Replace the word pick with edit for commit 4ea45e4. After that save the file and exit.

edit 4ea45e4 Split me. I am too big...
pick 923c105 Go ahead, read me...

If you are using Vim, you can save and exit by first hitting the Esc key to switch to the command mode. Once you are in command mode, type :x and then hit the Return key.

Step 6: The commit we are splitting adds three files to the repo: the_dude.md, walter.md and donny.md. Let’s make the first commit we are about to split to just about The Dude. For that, we need to first remove the other two files (walter.md and donny.md). We can easily do that by resetting those two files to the previous commit which doesn’t include them.

git reset HEAD~ walter.md donny.md

At this point, git status should show that walter.md and donny.md have been deleted from the staging area:

git status

rebase in progress; onto a258b8e
You are currently editing a commit while rebasing branch 'master' on 'a258b8e'.
  (use "git commit --amend" to amend the current commit)
  (use "git rebase --continue" once you are satisfied with your changes)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    donny.md
    deleted:    walter.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    donny.md
    walter.md

Step 7: Now we can ammend the original commit to include only the_dude.md file.

git commit --amend -m "The dude abides"

Step 8: Although the other two files (walter.md and donny.md) were removed from the staging area, they are not removed from filesystem. We can add them back to the staging area one at a time and create separate commits.

git add walter.md
git commit -m "You are entering a world of pain"
git add donny.md
git commit -m "Phone's ringing, Dude"

Step 9: Now that we have split the original commit into three separate commits, we need to tell Git to finish rebasing.

git rebase --continue

The Git history for split_dudeism repo should have total of six commits now.

git log --oneline

575f98c Go ahead, read me...
4eee259 Phone's ringing, Dude
f4db974 You are entering a world of pain
ad8533b The dude abides
a258b8e Are you going to a lebowski fest?
e61add7 Dudeism - this is where it all starts

Step 10: Finally let’s clean up by deleting the split_target branch.

git branch -D split_target

And we are done!!

 
7
Kudos
 
7
Kudos

Now read this

How to Debug Significant Location Change in iOS

If an app has registered to listen for significant location change notifications, but is subsequently terminated, iOS will automatically relaunch the app into the background, if a new notification arrives. iOS generates significant... Continue →