2010-11-27

Further Adventures In Git(/Hub)ery

This evening I decided to check if there were any outstanding pull requests for the SDK repository (to which I haven't been paying attention).

There were! The oldest was pull request 29 from Thomas Bassetto, which contains two small fixes (first, second) to the docs.

So I fetched the branch of his fork in which the changes reside:

$ git fetch https://github.com/tbassetto/addon-sdk.git master

But that branch (and the fork in general) is a few weeks out-of-date, so "git diff HEAD FETCH_HEAD" showed a bunch of changes, and it was unclear how painful the merge would be.

Thus I decided to try cherry-picking the changes, my first time using "git cherry-pick".

The first one went great:

$ git cherry-pick 8268334070d03a896d5c006d1b4db94d4cb44b17
Finished one cherry-pick.
[master ceadb1f] Fixed an internal link in the widget doc
 1 files changed, 1 insertions(+), 1 deletions(-)

Except that I realized afterward I hadn't added "r,a=myk" to the commit message. So I tried "git commit --amend" for the first time, which worked just fine:

$ git commit --amend
[master 2d674a6] Fixed an internal link in the widget doc; r,a=myk
 1 files changed, 1 insertions(+), 1 deletions(-)

Next time I'll remember to use the "--edit" flag to "git cherry-pick", which lets one "edit the commit message prior to committing."

The second cherry-pick was more complicated, because I only wanted one of the two changes in the commit (in my review, I had identified the second change as unnecessary); and, as it turned out, also because there was a merge conflict with other commits.

I started by cherry-picking the commit with the "--no-commit" option (so I could remove the second change):

$ git cherry-pick --no-commit 666ad7a99e05e338348dfc579d5b1f75e8d3bb1b
Automatic cherry-pick failed.  After resolving the conflicts,
mark the corrected paths with 'git add <paths>' or 'git rm <paths>' and commit the result.
When commiting, use the option '-c 666ad7a' to retain authorship and message.

The conflict was trivial, and I knew where it was, so I resolved it manually (instead of trying "git mergetool" for the first time), removed the second change, added the merged file, and committed the result, using the "-c" option to preserve the original author and commit message while allowing me to edit the message to add "r,a=myk":

$ git add packages/addon-kit/docs/request.md
$ git commit -c 666ad7a
[master 774d1cb] Completed the example in the Request module documentation; r,a=myk
 1 files changed, 1 insertions(+), 0 deletions(-)

Then I used "gitg" and "git log master ^upstream/master" to verify that the commits looked good to go, after which I pushed them:

$ git push upstream master
[git's standard obscure and disconcerting gobbledygook]

Finally, I closed the pull request with this comment that summarized what I did and provided links to the cherry-picked commits.

It would have been nice if the cherry-picked commit that didn't have merge conflicts (and which I didn't change in the process of merging) had kept its original commit ID, but I sense that that is somehow a fundamental violation of the model.

It would also have been nice if the cherry-picked commit messages had been automatically annotated with references to the original commits.

But overall the process seemed pretty reasonable, it was fairly easy to do what I wanted and recover from mistakes, and the author, committer, reviewer, and approver are clearly indicated in the cherry-picked commits (first, second).

[Also posted to the discussion group.]

3 comments:

matej said...

It would also have been nice if the cherry-picked commit messages had been automatically annotated with references to the original commits.

git cherry-pick -x

myk said...

Thanks Matej!

Anonymous said...

Seems this is about similar problems ?