Commit cd1e3d40 authored by smut@google.com's avatar smut@google.com

Add git cherry picking extension

This extension uploads a fake cherry pick-style diff to rietveld with a modified project parameter. The modified project is intended to be used by the commit queue to attempt to land the change on a branch.

This works by grabbing the parent of the targeted revision and generating the diff. It is intended to be used to CQ trivial cherry picks which apply cleanly on top of other branches without conflicts.

BUG=387111

Review URL: https://codereview.chromium.org/397593004

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@286273 0039d316-1c4b-4281-b951-d872f2087c98
parent fbfecb72
#!/usr/bin/env bash
# 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.
# git_cherry_pick_upload.py -- Upload a cherry pick CL to rietveld.
. $(type -P python_git_runner.sh)
#!/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())
This diff is collapsed.
'\" t
.\" Title: git-cherry-pick-upload
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
.\" Date: 07/23/2014
.\" Manual: Chromium depot_tools Manual
.\" Source: depot_tools dff725e
.\" Language: English
.\"
.TH "GIT\-CHERRY-PICK-UPLOAD" "1" "07/23/2014" "depot_tools dff725e" "Chromium depot_tools Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
git-cherry-pick-upload \- Upload the diff between a revision and its parent to rietveld\&.
.SH "SYNOPSIS"
.sp
.nf
\fIgit cherry-pick-upload\fR \-\-branch <remote_branch_name> <commit_hash>
.fi
.sp
.SH "DESCRIPTION"
.sp
git cherry-pick-upload is used to upload a cherry pick to rietveld\&. It uses your view of the remote to generate the diff between a revision and its parent, and then uploads that diff to rietveld\&.
.sp
The commit message is annotated with "(cherry picked from commit [parent sha1])" as if it were generated by git cherry\-pick \-x\&.
.SH "EXAMPLE"
.sp
.sp
.if n \{\
.RS 4
.\}
.nf
\fB$ git cherry-pick-upload \-h\fR
usage: git_cherry_pick_upload\&.py [\-h] \-\-branch <branch> <commit>
positional arguments:
<commit> SHA to cherry pick\&.
optional arguments:
\-h, \-\-help show this help message and exit
\-\-branch <branch>, \-b <branch>
The upstream branch to cherry pick to\&.
\fB$ git cherry-pick-upload \-b my_branch c02b7d24a066adb747fdeb12deb21bfa\fR
Found parent revision: b96d69fda53845a205151613a9c4cc93
Loaded authentication cookies from \&.codereview_upload_cookies
Issue created\&. URL: https://codereview\&.chromium\&.org/1234567890
Uploading base_file for some/path/first\&.file: OK
Uploading some/path/first\&.file: OK
Uploading base_file for some/path/second\&.file: OK
Uploading some/path/second\&.file: OK
Uploading base_file for some/path/third\&.file: OK
Uploading some/path/third\&.file: OK
Finalizing upload: OK
.fi
.if n \{\
.RE
.\}
.sp
.SH "SEE ALSO"
.sp
\fBgit-cherry-pick\fR(1) \fBgit-cl-upload\fR(1)
.SH "CHROMIUM DEPOT_TOOLS"
.sp
Part of the chromium \fBdepot_tools\fR(7) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
.SH "NOTES"
.IP " 1." 4
here
.RS 4
\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
.RE
Upload the diff between a revision and its parent to rietveld.
#!/usr/bin/env bash
. demo_repo.sh
run git cherry-pick-upload -h
echo
pcommand git cherry-pick-upload -b my_branch c02b7d24a066adb747fdeb12deb21bfa
echo 'Found parent revision: b96d69fda53845a205151613a9c4cc93'
echo 'Loaded authentication cookies from .codereview_upload_cookies'
echo 'Issue created. URL: https://codereview.chromium.org/1234567890'
echo ' Uploading base_file for some/path/first.file: OK'
echo ' Uploading some/path/first.file: OK'
echo ' Uploading base_file for some/path/second.file: OK'
echo ' Uploading some/path/second.file: OK'
echo ' Uploading base_file for some/path/third.file: OK'
echo ' Uploading some/path/third.file: OK'
echo 'Finalizing upload: OK'
git-cherry-pick-upload(1)
=============
NAME
----
git-cherry-pick-upload -
include::_git-cherry-pick-upload_desc.helper.txt[]
SYNOPSIS
--------
[verse]
'git cherry-pick-upload' --branch <remote_branch_name> <commit_hash>
DESCRIPTION
-----------
`git cherry-pick-upload` is used to upload a cherry pick to rietveld. It uses
your view of the remote to generate the diff between a revision and its parent,
and then uploads that diff to rietveld.
The commit message is annotated with "(cherry picked from commit [parent sha1])"
as if it were generated by `git cherry-pick -x`.
EXAMPLE
-------
demo:1[]
SEE ALSO
--------
linkgit:git-cherry-pick[1]
linkgit:git-cl-upload[1]
include::_footer.txt[]
// vim: ft=asciidoc:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment