cros_merge_to_branch: rewrite commit message

Sometimes cherry picking commits can lead to confused Change-Id behavior.
Explicitly rewrite this to a new value when uploading to a branch.

While we're here, add a "cherry picked from" message to help in back
tracking where changes came from.

BUG=chromium-os:35786
TEST=`cros_merge_to_branch 36718 r22` added a cherry pick line and tweaked the change-id
	see CL:36756 as the result
TEST=`cros_merge_to_branch -n 39046 R23 --debug` shows --reviewer getting added
TEST=`buildbot/run_tests` passed

Change-Id: I5f9b80bcd0d90e83aa8f6656a8324fd1ff5e7f64
Reviewed-on: https://gerrit.chromium.org/gerrit/36757
Reviewed-by: David James <davidjames@chromium.org>
Commit-Ready: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
diff --git a/scripts/cros_merge_to_branch.py b/scripts/cros_merge_to_branch.py
index a4ea1fa..323be7a 100644
--- a/scripts/cros_merge_to_branch.py
+++ b/scripts/cros_merge_to_branch.py
@@ -36,6 +36,7 @@
 
 import logging
 import os
+import re
 import shutil
 import sys
 import tempfile
@@ -86,19 +87,47 @@
       and including git push --dry-run.
   """
   upload_type = 'drafts' if draft else 'for'
+  # Download & setup the patch if need be.
+  patch.Fetch(work_dir)
   # Apply the actual change.
   patch.CherryPick(work_dir, inflight=True, leave_dirty=True)
 
   # Get the new sha1 after apply.
   new_sha1 = git.GetGitRepoRevision(work_dir)
 
+  # If the sha1 has changed, then rewrite the commit message.
+  if patch.sha1 != new_sha1:
+    msg = []
+    reviewers = set()
+    for line in patch.commit_message.splitlines():
+      if line.startswith('Reviewed-on: '):
+        line = 'Previous-' + line
+      elif line.startswith('Commit-Ready: ') or \
+           line.startswith('Reviewed-by: ') or \
+           line.startswith('Tested-by: '):
+        # If the tag is malformed, or the person lacks a name,
+        # then that's just too bad -- throw it away.
+        ele = re.split('[<>@]+', line)
+        if len(ele) == 4:
+          reviewers.add('@'.join(ele[-3:-1]))
+        continue
+      msg.append(line)
+    msg += [
+        '(cherry picked from commit %s)' % patch.sha1,
+    ]
+    git.RunGit(work_dir, ['commit', '--amend', '-F', '-'],
+               input='\n'.join(msg).encode('utf8'))
+
+    # Get the new sha1 after rewriting the commit message.
+    new_sha1 = git.GetGitRepoRevision(work_dir)
+
   # Create and use a LocalPatch to Upload the change to Gerrit.
   local_patch = cros_patch.LocalPatch(
       work_dir, patch.project_url, constants.PATCH_BRANCH,
       patch.tracking_branch, patch.remote, new_sha1)
   return local_patch.Upload(
       patch.project_url, 'refs/%s/%s' % (upload_type, branch),
-      carbon_copy=False, dryrun=dryrun)
+      carbon_copy=False, dryrun=dryrun, reviewers=reviewers)
 
 
 def _SetupWorkDirectoryForPatch(work_dir, patch, branch, manifest, email):