upload -t: Automatically include local branch name

If the -t flag is given to upload, the local branch name is
automatically sent to Gerrit Code Review as the topic branch name
for the change(s).  This requires the server to be Gerrit Code
Review v2.1.3-53-gd50c94e or later, which isn't widely deployed
right now, so the default is opt-out.

Change-Id: I034fcacb405b7cb909147152db427fe69dd7bcbf
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/project.py b/project.py
index 4e8fa0e..1b5d9a6 100644
--- a/project.py
+++ b/project.py
@@ -149,10 +149,11 @@
       R_HEADS + self.name,
       '--')
 
-  def UploadForReview(self, people):
+  def UploadForReview(self, people, auto_topic=False):
     self.project.UploadForReview(self.name,
                                  self.replace_changes,
-                                 people)
+                                 people,
+                                 auto_topic=auto_topic)
 
   def GetPublishedRefs(self):
     refs = {}
@@ -555,7 +556,10 @@
         return rb
     return None
 
-  def UploadForReview(self, branch=None, replace_changes=None, people=([],[])):
+  def UploadForReview(self, branch=None,
+                      replace_changes=None,
+                      people=([],[]),
+                      auto_topic=False):
     """Uploads the named branch for code review.
     """
     if branch is None:
@@ -587,10 +591,15 @@
       for e in people[1]:
         rp.append('--cc=%s' % sq(e))
 
+      ref_spec = '%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch)
+      if auto_topic:
+        ref_spec = ref_spec + '/' + branch.name
+
       cmd = ['push']
       cmd.append('--receive-pack=%s' % " ".join(rp))
       cmd.append(branch.remote.SshReviewUrl(self.UserEmail))
-      cmd.append('%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch))
+      cmd.append(ref_spec)
+
       if replace_changes:
         for change_id,commit_id in replace_changes.iteritems():
           cmd.append('%s:refs/changes/%s/new' % (commit_id, change_id))
diff --git a/subcmds/upload.py b/subcmds/upload.py
index 5a42611..569e31c 100644
--- a/subcmds/upload.py
+++ b/subcmds/upload.py
@@ -111,6 +111,9 @@
 """
 
   def _Options(self, p):
+    p.add_option('-t',
+                 dest='auto_topic', action='store_true',
+                 help='Send local branch name to Gerrit Code Review')
     p.add_option('--replace',
                  dest='replace', action='store_true',
                  help='Upload replacement patchesets from this branch')
@@ -121,7 +124,7 @@
                  type='string',  action='append', dest='cc',
                  help='Also send email to these email addresses.')
 
-  def _SingleBranch(self, branch, people):
+  def _SingleBranch(self, opt, branch, people):
     project = branch.project
     name = branch.name
     remote = project.GetBranch(name).remote
@@ -154,11 +157,11 @@
         answer = _ConfirmManyUploads()
 
     if answer:
-      self._UploadAndReport([branch], people)
+      self._UploadAndReport(opt, [branch], people)
     else:
       _die("upload aborted by user")
 
-  def _MultipleBranches(self, pending, people):
+  def _MultipleBranches(self, opt, pending, people):
     projects = {}
     branches = {}
 
@@ -227,7 +230,7 @@
       if not _ConfirmManyUploads(multiple_branches=True):
         _die("upload aborted by user")
 
-    self._UploadAndReport(todo, people)
+    self._UploadAndReport(opt, todo, people)
 
   def _AppendAutoCcList(self, branch, people):
     """
@@ -311,9 +314,9 @@
         _die("upload aborted by user")
 
     branch.replace_changes = to_replace
-    self._UploadAndReport([branch], people)
+    self._UploadAndReport(opt, [branch], people)
 
-  def _UploadAndReport(self, todo, original_people):
+  def _UploadAndReport(self, opt, todo, original_people):
     have_errors = False
     for branch in todo:
       try:
@@ -335,7 +338,7 @@
                     branch.error = 'User aborted'
                     continue
 
-        branch.UploadForReview(people)
+        branch.UploadForReview(people, auto_topic=opt.auto_topic)
         branch.uploaded = True
       except UploadError, e:
         branch.error = e
@@ -391,6 +394,6 @@
     if not pending:
       print >>sys.stdout, "no branches ready for upload"
     elif len(pending) == 1 and len(pending[0][1]) == 1:
-      self._SingleBranch(pending[0][1][0], people)
+      self._SingleBranch(opt, pending[0][1][0], people)
     else:
-      self._MultipleBranches(pending, people)
+      self._MultipleBranches(opt, pending, people)