Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
109 lines (79 sloc) 3.37 KB
layout title
post
Clean up Commits with git cherry-pick -n

Sometimes I binge code for like 3+ hours and work on several unrelated things. Since I'm so in the zone, I often forget to commit regularly, and am left with a bunch of changes not yet staged for commit when I take a break:

ffffffaaaacccckkkkkk!!!!!!!

First, I stage the changes:

$ git add .

And then create a new branch and prefix the branch name with wip

$ git checkout -b wip/clean-me

This produces a git log that looks like:

* 5a639f3  (HEAD, wip/clean-me) 48 seconds ago Jesse shawl
|  Please clean this branch|
|  five  | 0
|  four  | 0
|  one   | 0
|  seven | 0
|  six   | 0
|  three | 0
|  two   | 0
|  7 files changed, 0 insertions(+), 0 deletions(-)
|
* 24784a5  (master) 6 hours ago Jesse shawl
   initial commit
   readme.md | 0
   1 file changed, 0 insertions(+), 0 deletions(-)

I can always come back to this point as long as I commit, but in this post, I'll walk through the process of making sense of this otherwise meaningless commit.

Getting only the changes you want/need

Let's say that 5a639f3 contains a few hot fixes that should be added to master. I want to pull in the file changes to one, two, and three, but not four, five, six, and seven.

To move a commit to a new branch, you normally git cherry-pick 5a639f3 while on the master branch. But, this will just add a new commit on master that's identical to the wip/clean-me branch. This doesn't do much for us.

Instead, we can git cherry-pick -n 5a639f3 to cherry-pick the changes without making a commit. This will allow us to edit the index (or staging area) before making the next commit.

$ git cherry-pick -n 5a639f3

After running this command, git status will tell me that I have changes that need to be committed:

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

new file:   five
new file:   four
new file:   one
new file:   seven
new file:   six
new file:   three
new file:   two

At this point, I reset my HEAD to move these changes out of the staging area. This means that I can add back in the changes I want with git add <path> and/or view the diffs without having to use the --staged option.

$ git reset HEAD

You can now add the files you want to the staging area individually:

$ git add one two three

And finally, make the commit.

This leaves us with a git log that looks like:

* 07ac794  (HEAD, master) 6 seconds ago Jesse shawl
|  Add hotfixes that should be deployed asap|
|  one   | 0
|  three | 0
|  two   | 0
|  3 files changed, 0 insertions(+), 0 deletions(-)

| * 5a639f3  (wip/please-clean-me) 17 minutes ago Jesse shawl
|/   Please clean this branch|
|    five  | 0
|    four  | 0
|    one   | 0
|    seven | 0
|    six   | 0
|    three | 0
|    two   | 0
|    7 files changed, 0 insertions(+), 0 deletions(-)

* 24784a5  7 hours ago Jesse shawl
   initial commit
   readme.md | 0
   1 file changed, 0 insertions(+), 0 deletions(-)

At this point, we've added the important changes from the please-clean-me branch to master. The changes still exist on your existing branch if you need to go back later and make changes.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.