Get Off My Lawn

Adventures of a Curmudgeon

Cherry Picking Multiple Files With Git

Yesterday I was tasked with moving over a ‘feature’ from one branch into ‘master’ for eventual deployment, ahead of the rest of the planned features. And, I think, normally, this isn’t a big deal, especially with git. However, my challenge involved several iterations of this ‘feature’ and several changed files over a period of time.

Cherry Pick Time?

My first thought was to cherry-pick the commits into the ‘master’ branch. After I found the commits I needed to cherry-pick, I thought to myself, “How can I automate this?” That’s because I had 45 commits to process.

I did start down the cherry-pick lane. Using Tower, a Git GUI application, it quickly got old moving a commit into the branch, fixing any conflicts and commiting the change.

I really wanted to move the entire feature into ‘master’ as one unit. Yes I know there are ways to squash commits into one. But I was looking at dealing with 45 commits… and it was late in the evening… I just knew there had to be a better way.

Cherry Picking Multiple Files

Google’s my friend and I found an excellent article by Jason Rudolph describing exactly what I was trying to do: bring over a mess of files into a branch.

Heading back to Tower, I then cycled through the 45 commits to build me a list of 31 files that had either been added or changed in the implementation of this ‘feature’.

Then on the command-line:

$ git checkout master
$ git checkout -b local-merge-branch
$ git checkout development <file-1> <file-2> <file-3> ... <file-31>

Actually I did the checkout process over a couple of iterations. And I did it on a local branch to make sure I didn’t screw anything up. It also allowed me to package all the changes into a single unit.

Running my tests produced a failed test. “Crap!”, I thought. What did I miss? Turns out I didn’t miss anything because the failure was in an unrelated test. I just backed out the changes that was causing the failure.

Once I had the Green light (i.e. all tests passing), I stashed my changes:

$ git stash save changes-destined-for-master

And then applied them to ‘master’:

$ git checkout master
$ git stash pop

I run the tests one final time; just being thorough. After the tests finished, I committed and tagged.

Want to learn how…

I would love it if someone could offer suggestions on automating this process.

Is there a way of getting a list of affected files by searching commit messages for a token (in this case it was a Issue Ticket number)?

Is there a better way of accomplishing the same thing?

Is there a way to automate cherry picking?

Until I learn a better way, I’ll use this as an example of moving changed/added files from one branch to another.