~/ 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.
~/ Posted by Jesse Shawl on 2014-05-23