Wednesday, January 18, 2017

Hello patch-id, my old friend.

I started off with a series of patches that I'd cherry-picked out of one branch into my current branch. All seemed good, so I was ready to merge them. Except something happened to the upstream and I was unable to actually push my commits. Now, though, I'm presented with an interesting mess. I have my own series that I know I've tested, the branch from which I've cherry-picked them has a ton of unrelated (and untested by me) commits and I want to enlist someone's help with getting these dozen commits merged into the main development branch.

How do I do this?

Well, I thought, first off we'll ensure my tree is clean.

   # git fetch --all --tags
   # git status
   On branch master
   Your branch is ahead of 'oe/master' by 12 commits.
     (use "git push" to publish your local commits)

   nothing to commit, working directory clean

All's good. Next, let's go ensure all of our commits are in the upstream branch, trusting the summary line to be good enough as a first indicator because there's no way I would've touched the summary in my tree when cherry-picking or amending or anything. The only failure would be if something in my tree has subsequently gone missing from the up-stream -next tree. And given this is a -next tree and not intended to be fast-forward, this seems like a reasonable thing to check.

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --oneline --grep={} oe/master-next

Works pretty well it seems. Numbers check?

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --oneline --grep={} oe/master-next | wc -l

Yup. Okay, now we have essentially two lists of commit ids. My branch and the upstream branch where I picked from. Let's make sure those commits are basically the same.  We'll do this with git-patch-id, a tool that, in ancient times, I created by hand by formatting patches out of my tree and then doing an md5 (it was ancient times, leave me alone) of the patches without headers.  Apparently I wasn't the only one doing this sort of crime, because now git has something very much like that built right in.  Truly we live in an age of wonders.

Moving on.

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --pretty="format:%H " --grep={} oe/master-next | \
   > xargs -n1 -i sh -c 'git show {} | git patch-id' > upstream.txt

   # git log --pretty="format:'%s'" oe/master..HEAD| \
   > xargs -n1 -i git log --pretty="format:%H " --grep={} | \
   > xargs -n1 -i sh -c 'git show {} | git patch-id' > local.txt

So, with a dozen patches, it's easy enough to just visually compare them, but I figured I'd go the one extra step and automate comparison of the lists as well.

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --pretty="format:%H " --grep={} oe/master-next | \
   > xargs -n1 -i sh -c 'git show {} | git patch-id' | cut -f1 -d' ' \
   > > upstream.txt

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --pretty="format:%H " --grep={} | \
   > xargs -n1 -i sh -c 'git show {} | git patch-id' | cut -f1 -d' ' \
   > > local.txt

   # diff upstream.txt local.txt

And in my case this revealed that I had one commit that was substantially different, since patch-id returned differences. On closer examination of the commit ids in each tree it was obvious that I'd made a significant change based on a discussion with the author and I'd said I would make the discussed change in place rather than requesting a new patch. So ultimately this was all worth it.