Index: git_cherry_pick_upload.py |
diff --git a/git_cherry_pick_upload.py b/git_cherry_pick_upload.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..2a048faae37db55c2f2a920bb8f685cfdfe4f7ae |
--- /dev/null |
+++ b/git_cherry_pick_upload.py |
@@ -0,0 +1,144 @@ |
+#!/usr/bin/env python |
+# Copyright 2014 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""Upload a cherry pick CL to rietveld.""" |
+ |
+import argparse |
+import md5 |
+import subprocess2 |
+import sys |
+ |
+from git_cl import Changelist |
+from git_common import config, run |
+from third_party.upload import EncodeMultipartFormData, GitVCS |
+from rietveld import Rietveld |
+ |
+ |
+def cherry_pick(target_branch, commit): |
+ """Attempt to upload a cherry pick CL to rietveld. |
+ |
+ Args: |
+ target_branch: The branch to cherry pick onto. |
+ commit: The git hash of the commit to cherry pick. |
+ """ |
+ author = config('user.email') |
+ |
+ description = '%s\n\n(cherry picked from commit %s)\n' % ( |
+ run('show', '--pretty=%B', '--quiet', commit), commit) |
+ |
+ parent = run('show', '--pretty=%P', '--quiet', commit) |
+ print 'Found parent revision:', parent |
+ |
+ class Options(object): |
+ def __init__(self): |
+ self.emulate_svn_auto_props = False |
+ |
+ content_type, payload = EncodeMultipartFormData([ |
+ ('base', '%s@%s' % (Changelist().GetRemoteUrl(), target_branch)), |
+ ('cc', config('rietveld.cc')), |
+ ('content_upload', '1'), |
+ ('description', description), |
+ ('project', '%s@%s' % (config('rietveld.project'), target_branch)), |
+ ('subject', description.splitlines()[0]), |
+ ('user', author), |
+ ], [ |
+ ('data', 'data.diff', GitVCS(Options()).PostProcessDiff( |
+ run('diff', parent, commit))), |
+ ]) |
+ |
+ rietveld = Rietveld(config('rietveld.server'), author, None) |
+ # pylint: disable=W0212 |
+ output = rietveld._send( |
+ '/upload', |
+ payload=payload, |
+ content_type=content_type, |
+ ).splitlines() |
+ |
+ # If successful, output will look like: |
+ # Issue created. URL: https://codereview.chromium.org/1234567890 |
+ # 1 |
+ # 10001 some/path/first.file |
+ # 10002 some/path/second.file |
+ # 10003 some/path/third.file |
+ |
+ if output[0].startswith('Issue created. URL: '): |
+ print output[0] |
+ issue = output[0].rsplit('/', 1)[-1] |
+ patchset = output[1] |
+ files = output[2:] |
+ |
+ for f in files: |
+ file_id, filename = f.split() |
+ mode = 'M' |
+ |
+ try: |
+ content = run('show', '%s:%s' % (parent, filename)) |
+ except subprocess2.CalledProcessError: |
+ # File didn't exist in the parent revision. |
+ content = '' |
+ mode = 'A' |
+ |
+ content_type, payload = EncodeMultipartFormData([ |
+ ('checksum', md5.md5(content).hexdigest()), |
+ ('filename', filename), |
+ ('is_current', 'False'), |
+ ('status', mode), |
+ ], [ |
+ ('data', filename, content), |
+ ]) |
+ |
+ # pylint: disable=W0212 |
+ print ' Uploading base file for %s:' % filename, rietveld._send( |
+ '/%s/upload_content/%s/%s' % (issue, patchset, file_id), |
+ payload=payload, |
+ content_type=content_type, |
+ ) |
+ |
+ try: |
+ content = run('show', '%s:%s' % (commit, filename)) |
+ except subprocess2.CalledProcessError: |
+ # File no longer exists in the new commit. |
+ content = '' |
+ mode = 'D' |
+ |
+ content_type, payload = EncodeMultipartFormData([ |
+ ('checksum', md5.md5(content).hexdigest()), |
+ ('filename', filename), |
+ ('is_current', 'True'), |
+ ('status', mode), |
+ ], [ |
+ ('data', filename, content), |
+ ]) |
+ |
+ # pylint: disable=W0212 |
+ print ' Uploading %s:' % filename, rietveld._send( |
+ '/%s/upload_content/%s/%s' % (issue, patchset, file_id), |
+ payload=payload, |
+ content_type=content_type, |
+ ) |
+ |
+ # pylint: disable=W0212 |
+ print 'Finalizing upload:', rietveld._send('/%s/upload_complete/1' % issue) |
+ |
+ |
+def main(): |
+ parser = argparse.ArgumentParser() |
+ parser.add_argument( |
+ '--branch', |
+ '-b', |
+ help='The upstream branch to cherry pick to.', |
+ metavar='<branch>', |
+ required=True, |
+ ) |
+ parser.add_argument( |
+ 'commit', |
+ help='SHA to cherry pick.', |
+ metavar='<commit>', |
+ ) |
+ args = parser.parse_args() |
+ cherry_pick(args.branch, args.commit) |
+ |
+if __name__ == '__main__': |
+ sys.exit(main()) |