Git-ing Drupal contrib patches done

In not-so-recent news, Drupal migrated the drupal.org project repository from CVS to Git in late February, 2011. My experience with Git previous to this has been as a user fetching source code of x.org, mesa, dri, and other various Linux and Unix projects.

As a user, not a developer, I found the Git work flow confusing. I did not need to make local commits and it was hard to wrap my head around bringing in changes from multiple remote repositories.

As a PHP developer, I first grasped the work flow at Columbus GiveCamp 2010 when I needed to make a github account for the branch of the Audio module we hacked on. As well, some Ruby guy had a nice Git work flow diagram, which I promptly forgot all about until the not-so-recent event above. In recent news, I have been hacking on Drupal 7 versions of several modules.

In this particular case, the module had a Drupal 7 branch already, but the code was so out of date that I branched from the latest Drupal 6 changes (think 8kb v 32kb diffs). Eventually I ended up with a nice local branch, 7.x-3.x, and the module maintainer requested that I branch from origin/7.x-3.x instead of origin/6.x-3.x.

In either case, I thought, after reading man git and other manual pages, that I could simply do the following command to generate community friendly Git patches.

git format-patch origin/7.x-3.x..7.x-3.x
git checkout -b 7.x-fresh origin/7.x-3.x
git apply (17 patches)

Fail. It also failed when I made patches from origin/6.x-3.x.

Unfortunately, it seems that Git can create patches that it can’t actually apply

Wait. What. Did anyone else think this was a dumb idea before it was implemented?

If you’re not part of the main development team and just want to contribute some code these become headaches. You still want credit for your work (i.e. commit history).

I thought that I would have to make a community-unfriendly sentiment such as this:

git diff origin/7.x-3.x..7.x-3.x > blah.patch
git checkout -b 7.x-3.x-origin origin/7.x-3.x
patch -p1 < blah.patch
git add (new files to add)
git commit -a (comment git sucks)
git format-patch (commit)
git checkout -b 7.x-3.x-fresh origin/7.x-3.x
git apply (formatted-patch)

I have been very timid about the rebase feature because the documentation on what rebase actually does is confusing. That is, it’s more confusing than the rest of Git documentation. Do you keep HEAD changes or do you revert to the patch’s change?

I decided to give up. However, I knew it was not not possible because every day I get spams from mailing lists spamming patches via git format-patch. So a few minutes after giving up, I tried again. I thought I went through rebasing correctly, but I did not commit with each merge conflict.

Not not possible

The work flow ended up a bit more like this:

git checkout 7.x-3.x
git rebase origin/7.x-3.x      (because 7.x-3.x is a branch off of 6.x-3.x)
(fix merge conflicts and choose HEAD)
git add (file)
git commit
git rebase --continue           (or --skip when told to)
(go to fix merge conflicts until done)
git format-patch (commit in origin/7.x-3.x to diff from)
git checkout -b 7.x-3.x-fresh origin/7.x-3.x
git apply (patches)

Success! And the git log history looks cleaner.

Hindsight

In hindsight I probably should not have originally branched from 6.x-3.x. Instead I should have rebased 7.x-3.x to 6.x-3.x and then re-ported to Drupal 7.