git cl: use gnumbd config instead of PENDING_REF_PREFIX of codereview.settings.

BUG=chromium:642493,672043
R=machenbach@chromium.org,iannucci@chromium.org

Change-Id: I0abc31b95b1766fd5fd24c1379b538d0c5291011
Reviewed-on: https://chromium-review.googlesource.com/417259
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
diff --git a/git_cl.py b/git_cl.py
index c80184c..8b7c4ea 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -87,6 +87,12 @@
 # Initialized in main()
 settings = None
 
+# Used by tests/git_cl_test.py to add extra logging.
+# Inside the weirdly failing test, add this:
+# >>> self.mock(git_cl, '_IS_BEING_TESTED', True)
+# And scroll up to see the strack trace printed.
+_IS_BEING_TESTED = False
+
 
 def DieWithError(message):
   print(message, file=sys.stderr)
@@ -1028,19 +1034,6 @@
     return RunGit(['config', param], **kwargs).strip()
 
 
-def ShouldGenerateGitNumberFooters():
-  """Decides depending on codereview.settings file in the current checkout HEAD.
-  """
-  # TODO(tandrii): this has to be removed after Rietveld is read-only.
-  # see also bugs http://crbug.com/642493 and http://crbug.com/600469.
-  cr_settings_file = FindCodereviewSettingsFile()
-  if not cr_settings_file:
-    return False
-  keyvals = gclient_utils.ParseCodereviewSettingsContent(
-      cr_settings_file.read())
-  return keyvals.get('GENERATE_GIT_NUMBER_FOOTERS', '').lower() == 'true'
-
-
 class _GitNumbererState(object):
   KNOWN_PROJECTS_WHITELIST = [
       'chromium/src',
@@ -1126,6 +1119,8 @@
           return out.strip().splitlines()
         return []
       enabled, disabled = map(get_opts, ['enabled', 'disabled'])
+    logging.info('validator config enabled %s disabled %s refglobs for '
+                 '(this ref: %s)', enabled, disabled, ref)
 
     if cls.match_refglobs(ref, disabled):
       return False
@@ -1152,8 +1147,13 @@
 
   def __init__(self, pending_prefix, validator_enabled):
     # TODO(tandrii): remove pending_prefix after gnumbd is no more.
+    if pending_prefix:
+      if not pending_prefix.endswith('/'):
+        pending_prefix += '/'
     self._pending_prefix = pending_prefix or None
     self._validator_enabled = validator_enabled or False
+    logging.debug('_GitNumbererState(pending: %s, validator: %s)',
+                  self._pending_prefix, self._validator_enabled)
 
   @property
   def pending_prefix(self):
@@ -2352,7 +2352,8 @@
     if remote_url:
       remote, remote_branch = self.GetRemoteBranch()
       target_ref = GetTargetRef(remote, remote_branch, options.target_branch,
-                                settings.GetPendingRefPrefix())
+                                pending_prefix_check=True,
+                                remote_url=self.GetRemoteUrl())
       if target_ref:
         upload_args.extend(['--target_ref', target_ref])
 
@@ -2805,8 +2806,9 @@
     gerrit_remote = 'origin'
 
     remote, remote_branch = self.GetRemoteBranch()
+    # Gerrit will not support pending prefix at all.
     branch = GetTargetRef(remote, remote_branch, options.target_branch,
-                          pending_prefix='')
+                          pending_prefix_check=False)
 
     if options.squash:
       self._GerritCommitMsgHookCheck(offer_removal=not options.force)
@@ -4248,14 +4250,17 @@
   return 'I%s' % change_hash.strip()
 
 
-def GetTargetRef(remote, remote_branch, target_branch, pending_prefix):
+def GetTargetRef(remote, remote_branch, target_branch, pending_prefix_check,
+                 remote_url=None):
   """Computes the remote branch ref to use for the CL.
 
   Args:
     remote (str): The git remote for the CL.
     remote_branch (str): The git remote branch for the CL.
     target_branch (str): The target branch specified by the user.
-    pending_prefix (str): The pending prefix from the settings.
+    pending_prefix_check (bool): If true, determines if pending_prefix should be
+      used.
+    remote_url (str): Only used for checking if pending_prefix should be used.
   """
   if not (remote and remote_branch):
     return None
@@ -4297,9 +4302,12 @@
                                           'refs/heads/')
   elif remote_branch.startswith('refs/remotes/branch-heads'):
     remote_branch = remote_branch.replace('refs/remotes/', 'refs/')
-  # If a pending prefix exists then replace refs/ with it.
-  if pending_prefix:
-    remote_branch = remote_branch.replace('refs/', pending_prefix)
+
+  if pending_prefix_check:
+    # If a pending prefix exists then replace refs/ with it.
+    state = _GitNumbererState.load(remote_url, remote_branch)
+    if state.pending_prefix:
+      remote_branch = remote_branch.replace('refs/', state.pending_prefix)
   return remote_branch
 
 
@@ -4635,11 +4643,19 @@
       RunGit(['cherry-pick', cherry_pick_commit])
     if cmd == 'land':
       remote, branch = cl.FetchUpstreamTuple(cl.GetBranch())
+      logging.debug('remote: %s, branch %s', remote, branch)
       mirror = settings.GetGitMirror(remote)
-      pushurl = mirror.url if mirror else remote
-      pending_prefix = settings.GetPendingRefPrefix()
+      if mirror:
+        pushurl = mirror.url
+        git_numberer = _GitNumbererState.load(pushurl, branch)
+      else:
+        pushurl = remote  # Usually, this is 'origin'.
+        git_numberer = _GitNumbererState.load(
+            RunGit(['config', 'remote.%s.url' % remote]).strip(), branch)
 
-      if ShouldGenerateGitNumberFooters():
+      pending_prefix = git_numberer.pending_prefix
+
+      if git_numberer.should_git_number:
         # TODO(tandrii): run git fetch in a loop + autorebase when there there
         # is no pending ref to push to?
         logging.debug('Adding git number footers')
@@ -4699,6 +4715,12 @@
         revision = re.match(
           '.*?\nCommitted r(\\d+)', output, re.DOTALL).group(1)
     logging.debug(output)
+  except:  # pylint: disable=W0702
+    if _IS_BEING_TESTED:
+      logging.exception('this is likely your ACTUAL cause of test failure.\n'
+                        + '-' * 30 + '8<' + '-' * 30)
+      logging.error('\n' + '-' * 30 + '8<' + '-' * 30 + '\n\n\n')
+    raise
   finally:
     # And then swap back to the original branch and clean up.
     RunGit(['checkout', '-q', cl.GetBranch()])
@@ -4721,7 +4743,6 @@
       killed = True
 
   if cl.GetIssue():
-    # TODO(tandrii): figure out story of to pending + git numberer.
     to_pending = ' to pending queue' if pushed_to_pending else ''
     viewvc_url = settings.GetViewVCUrl()
     if not to_pending: