Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split last commit into two in Git

I have two working branches, master and forum and I've just made some modifications in forum branch, that I'd like to cherry-pick into master. But unfortunately, the commit I want to cherry-pick also contains some modifications that I don't want.

The solution would probably be to somehow delete the wrong commit and replace it with two separate commits, one with changes I want to pick in master, and others that doesn't belong there.

I've tried doing

git reset --hard HEAD^ 

which deleted all changes, so I had to go back with

git reset ORIG_HEAD 

So my question is, what is the best way to split last commit into two separate commits?

like image 576
Jakub Arnold Avatar asked Sep 17 '09 16:09

Jakub Arnold


People also ask

How do you strip a commit?

To remove the last commit from git, you can simply run git reset --hard HEAD^ If you are removing multiple commits from the top, you can run git reset --hard HEAD~2 to remove the last two commits. You can increase the number to remove even more commits.


1 Answers

You should use the index. After doing a mixed reset ("git reset HEAD^"), add the first set of changes into the index, then commit them. Then commit the rest.

You can use "git add" to put all changes made in a file to the index. If you don't want to stage every modification made in a file, only some of them, you can use "git add -p".

Let's see an example. Let's suppose I had a file called myfile, which contains the following text:

something something else something again 

I modified it in my last commit so that now it looks like this:

1 something something else something again 2 

Now I decide that I want to split it into two, and I want the insertion of the first line to be in the first commit, and the insertion of the last line to be in the second commit.

First I go back to HEAD's parent, but I want to keep the modifications in file system, so I use "git reset" without argument (which will do a so-called "mixed" reset):

$ git reset HEAD^ myfile: locally modified $ cat myfile 1 something something else something again 2 

Now I use "git add -p" to add the changes I want to commit to the index (=I stage them). "git add -p" is an interactive tool that asks you about what changes to the file should it add to the index.

$ git add -p myfile diff --git a/myfile b/myfile index 93db4cb..2f113ce 100644 --- a/myfile +++ b/myfile @@ -1,3 +1,5 @@ +1  something  something else  something again +2 Stage this hunk [y,n,a,d,/,s,e,?]? s    # split this section into two! Split into 2 hunks. @@ -1,3 +1,4 @@ +1  something  something else  something again Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y  # yes, I want to stage this @@ -1,3 +2,4 @@  something  something else  something again +2 Stage this hunk [y,n,a,d,/,K,g,e,?]? n   # no, I don't want to stage this 

Then I commit this first change:

$ git commit -m "Added first line" [master cef3d4e] Added first line  1 files changed, 1 insertions(+), 0 deletions(-) 

Now I can commit all the other changes (namely the numeral "2" put in the last line):

$ git commit -am "Added last line" [master 5e284e6] Added last line  1 files changed, 1 insertions(+), 0 deletions(-) 

Let's check the log to see what commits we have:

$ git log -p -n2 | cat Commit 5e284e652f5e05a47ad8883d9f59ed9817be59d8 Author: ... Date: ...      Added last line  Diff --git a/myfile b/myfile Index f9e1a67..2f113ce 100644 --- a/myfile +++ b/myfile @@ -2,3 +2,4 @@  something  something else  something again +2  Commit cef3d4e0298dd5d279a911440bb72d39410e7898 Author: ... Date: ...      Added first line  Diff --git a/myfile b/myfile Index 93db4cb..f9e1a67 100644 --- a/myfile +++ b/myfile @@ -1,3 +1,4 @@ +1  something  something else  something again 
like image 100
hcs42 Avatar answered Oct 11 '22 12:10

hcs42