Find, upload and apply patchset dependencies.

Here is an explanation of the changes in each module:

* git_cl.py -
IF a local branch is being tracked AND a CL has been uploaded there THEN use the CL's issue number and latest patchset as a dependency.

* upload.py -
Uploads the patchset dependency, if it exists, to Rietveld (Rietveld will be able to parse this when https://codereview.chromium.org/1155513002/ lands).

* rietveld.py -
Adds utility methods to get patchset dependencies from the new Rietveld endpoint (the endpoint will exist when https://codereview.chromium.org/1155513002/ lands).

* apply_issue.py -
If CL3 depends on CL2 which in turn depends on CL1 then apply_issue will gather a list of all issues and patchsets to apply (Eg: [CL1:PS1, CL2:PS1, CL3:PS2]).
apply_issue will then loop over the list applying each dependency.
Note: The apply_issue.py diff looks much worse than it is. Please see my comment in
https://codereview.chromium.org/1149653002/diff/260001/apply_issue.py#oldcode169


Tested end-to-end using a test Git repository (https://skia.googlesource.com/skiabot-test/) and the following CLs created in my test Rietveld instance:
* https://skia-codereview-staging.appspot.com/931002  ('Branch1 CL')
* https://skia-codereview-staging.appspot.com/5001001 ('Branch2 CL')
* https://skia-codereview-staging.appspot.com/9881001 ('Branch3 CL')
* https://skia-codereview-staging.appspot.com/3951001 ('Branch3.1 CL')
Opt into the new UI and observe the new 'Depends on Patchset' and 'Dependent Patchsets' sections in the above CLs.


Design doc is here: https://docs.google.com/document/d/1KZGFKZpOPvco81sYVRCzwlnjGctup71RAzY0MSb0ntc/edit#heading=h.6r6lt4tsvssw

BUG=502255

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=295778

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@295799 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/git_cl.py b/git_cl.py
index f719254..288e281 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -2185,6 +2185,28 @@
     if target_ref:
       upload_args.extend(['--target_ref', target_ref])
 
+    # Look for dependent patchsets. See crbug.com/480453 for more details.
+    remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch())
+    upstream_branch = ShortBranchName(upstream_branch)
+    if remote is '.':
+      # A local branch is being tracked.
+      local_branch = ShortBranchName(upstream_branch)
+      auth_config = auth.extract_auth_config_from_options(options)
+      branch_cl = Changelist(branchref=local_branch, auth_config=auth_config)
+      branch_cl_issue_url = branch_cl.GetIssueURL()
+      branch_cl_issue = branch_cl.GetIssue()
+      branch_cl_patchset = branch_cl.GetPatchset()
+      if branch_cl_issue_url and branch_cl_issue and branch_cl_patchset:
+        upload_args.extend(
+            ['--depends_on_patchset', '%s:%s' % (
+                 branch_cl_issue, branch_cl_patchset)])
+        print
+        print ('The current branch (%s) is tracking a local branch (%s) with '
+               'an open CL.') % (cl.GetBranch(), local_branch)
+        print 'Adding %s/#ps%s as a dependency patchset.' % (
+            branch_cl_issue_url, branch_cl_patchset)
+        print
+
   project = settings.GetProject()
   if project:
     upload_args.extend(['--project', project])