Robustly set issue number

When using "git cl patch -b branch_name issue_number" to resolve merge
conflicts in an uploaded CL the cherry-pick stage will probably fail due
to the expected merge conflicts. If you resolve the conflict and then
upload the now-merged CL you will actually create a new CL. This happens
because the SetIssue step is skipped when the cherry-pick fails.

This change sets the issue whenever a new branch is created. This is
safe (the new branch is not being used for anything else) and will
improve the situation in many cases.

crrev.com/c/2636593 is an example of a CL that was accidentally uploaded
as new when it was just supposed to be a resolving of merge conflicts on
an existing CL.

This change was manually tested with crrev.com/c/2107132.

Change-Id: Icb5b8e38feb6f0fa4a007d3924c4d69d2ee4937c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2638979
Commit-Queue: Bruce Dawson <brucedawson@chromium.org>
Reviewed-by: Gavin Mak <gavinmak@google.com>
diff --git a/git_cl.py b/git_cl.py
index d54b46c..9b943d2 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -2006,7 +2006,8 @@
         break
     return 0
 
-  def CMDPatchWithParsedIssue(self, parsed_issue_arg, nocommit, force):
+  def CMDPatchWithParsedIssue(self, parsed_issue_arg, nocommit, force,
+                              newbranch):
     assert parsed_issue_arg.valid
 
     self.issue = parsed_issue_arg.issue
@@ -2047,6 +2048,11 @@
 
     RunGit(['fetch', fetch_info['url'], fetch_info['ref']])
 
+    # If we have created a new branch then do the "set issue" immediately in
+    # case the cherry-pick fails, which happens when resolving conflicts.
+    if newbranch:
+      self.SetIssue(parsed_issue_arg.issue)
+
     if force:
       RunGit(['reset', '--hard', 'FETCH_HEAD'])
       print('Checked out commit for change %i patchset %i locally' %
@@ -4390,7 +4396,8 @@
       RunGit(['pull'])
 
     target_issue_arg = ParseIssueNumberArgument(cl.GetIssue())
-    return cl.CMDPatchWithParsedIssue(target_issue_arg, options.nocommit, False)
+    return cl.CMDPatchWithParsedIssue(target_issue_arg, options.nocommit, False,
+                                      False)
 
   if len(args) != 1 or not args[0]:
     parser.error('Must specify issue number or URL.')
@@ -4415,8 +4422,8 @@
   if not args[0].isdigit():
     print('canonical issue/change URL: %s\n' % cl.GetIssueURL())
 
-  return cl.CMDPatchWithParsedIssue(
-      target_issue_arg, options.nocommit, options.force)
+  return cl.CMDPatchWithParsedIssue(target_issue_arg, options.nocommit,
+                                    options.force, options.newbranch)
 
 
 def GetTreeStatus(url=None):