Splitting Your Last Commit in Git
Have you ever had a huge commit? And you want to split into multiple commits? Here is one of the way to go
- Start an interactive rebase with the commit SHA1 before the commit you want to split.
git rebase -i sha1
- git will open up vim or whatever default editor is with the commit you want to split. Mark this commit as ‘e’ or ‘edit’ instead of pick which would be the default. Save and exit from the editor.
- Now, let us reset the last commit
git reset HEAD^
- Now we can see the last commit to be un-done. And all your files from your last commit are either un-tracked / un-staged.
- Add the commits you want to group using ‘git add’ and ‘git commit’
- Once splitting of your commits are done. Continue re-basing
git rebase --continue
- If you end up with any merge conflict, resolve them.
- You have successfully split the commits.
Let us run through this with an example
-
Create a new folder and initialize a git repo there
mkdir example && cd example && git init
-
Add a file, to do the first commit
touch a.txt git add a.txt git commit -am "Added First commit"
-
Next create the larger commit you want to split
echo "Hello World" >> a.txt touch b.txt touch c.txt touch d.txt git add a.txt b.txt c.txt d.txt git commit -m "Added Large commit"
-
Start an interactive rebase with first commits SHA
git log --pretty=oneline
38bfe60742d74a4ac0e3a04b768ee0f5cb094e58 (HEAD -> master) Added Large commit ad51155ad7bf3f368c553000d1f74425a8664eb2 Added First commit
git rebase -i ad51155ad
-
Mark the commit as edit/e instead of pick
e 38bfe60 Added Large commit
- Save & Exit
- Reset HEAD by 1 commit
git reset HEAD^
Unstaged changes after reset: M a.txt
git status
interactive rebase in progress; onto ad51155 Last command done (1 command done): edit 38bfe60 Added Large commit No commands remaining. You are currently splitting a commit while rebasing branch 'master' on 'ad51155'. (Once your working directory is clean, run "git rebase --continue") Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: a.txt Untracked files: (use "git add <file>..." to include in what will be committed) b.txt c.txt d.txt no changes added to commit (use "git add" and/or "git commit -a")
-
Split your commits as you like.
git add a.txt git commit -m "Edited a.txt" git add b.txt git commit -m "Added b.txt" git add c.txt git commit -m "Added c.txt" git add d.txt git commit -m "Added d.txt"
-
Continue the rebase
git rebase --continue
Successfully rebased and updated refs/heads/master.
-
Check your git log to see the cleaner commit history
git log --pretty=oneline
a8b391dcfe1b18992d26daa9a7841e1a88235bc3 (HEAD -> master) Added d.txt 134f11f3c59d7f70d3d8f5946dca7491ed3b7790 Added c.txt d2ee4690e4482808c8453e16b767e86c9c405d40 Added b.txt f4393b44183ad000b7ab9c5fa3e3f785f12cab83 Edited a.txt ad51155ad7bf3f368c553000d1f74425a8664eb2 Added First commit