Переглянути джерело

Support dormant branches in the git map-branches output.

This adds support in two ways:
1. Displays a "(dormant)" marker as part of each branch's line when the
   verbosity level is four or above. ('git bmap -v -v -v -v ...'). It's
   worth noting that, with verbosity level 4, each line is now 119
   characters long; verbosity level 3 is 107.
2. Enables callers to hide dormant branches using a new '--hide-dormant'
   option. If the dormant branch is the parent of non-dormant branches,
   it's still shown, despite being dormant, so that it can continue to
   serve as the parent line for non-dormant branches.

Change-Id: I0504419fd12357563288b5d53bc49ca68a876e8f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4654849
Reviewed-by: Aravind Vasudevan <aravindvasudev@google.com>
Commit-Queue: Orr Bernstein <orrb@google.com>
Orr Bernstein 2 роки тому
батько
коміт
b7e16d28f6
2 змінених файлів з 44 додано та 8 видалено
  1. 2 1
      git_common.py
  2. 42 7
      git_map_branches.py

+ 2 - 1
git_common.py

@@ -821,12 +821,13 @@ def run_with_stderr(*cmd, **kwargs):
   autostrip = kwargs.pop('autostrip', True)
   indata = kwargs.pop('indata', None)
   decode = kwargs.pop('decode', True)
+  accepted_retcodes = kwargs.pop('accepted_retcodes', [0])
 
   cmd = (GIT_EXE, '-c', 'color.ui=never') + cmd
   proc = subprocess2.Popen(cmd, **kwargs)
   ret, err = proc.communicate(indata)
   retcode = proc.wait()
-  if retcode != 0:
+  if retcode not in accepted_retcodes:
     raise subprocess2.CalledProcessError(retcode, cmd, os.getcwd(), ret, err)
 
   if autostrip:

+ 42 - 7
git_map_branches.py

@@ -69,6 +69,10 @@ class OutputManager(object):
     for i, col in enumerate(line.columns):
       self.max_column_lengths[i] = max(self.max_column_lengths[i], len(col))
 
+  def merge(self, other):
+    for line in other.lines:
+      self.append(line)
+
   def as_formatted_string(self):
     return '\n'.join(
         l.as_padded_string(self.max_column_lengths) for l in self.lines)
@@ -116,6 +120,7 @@ class BranchMapper(object):
     self.verbosity = 0
     self.maxjobs = 0
     self.show_subject = False
+    self.hide_dormant = False
     self.output = OutputManager()
     self.__gone_branches = set()
     self.__branches_info = None
@@ -172,7 +177,7 @@ class BranchMapper(object):
 
     if roots:
       for root in sorted(roots):
-        self.__append_branch(root)
+        self.__append_branch(root, self.output)
     else:
       no_branches = OutputLine()
       no_branches.append('No User Branches')
@@ -214,9 +219,27 @@ class BranchMapper(object):
 
     return color
 
-  def __append_branch(self, branch, depth=0):
+  def __is_dormant_branch(self, branch):
+    if '/' in branch:
+      return False
+
+    is_dormant = run('config',
+                     '--get',
+                     'branch.{}.dormant'.format(branch),
+                     accepted_retcodes=[0, 1])
+    return is_dormant == 'true'
+
+  def __append_branch(self, branch, output, depth=0):
     """Recurses through the tree structure and appends an OutputLine to the
     OutputManager for each branch."""
+    child_output = OutputManager()
+    for child in sorted(self.__parent_map.pop(branch, ())):
+      self.__append_branch(child, child_output, depth=depth + 1)
+
+    is_dormant_branch = self.__is_dormant_branch(branch)
+    if self.hide_dormant and is_dormant_branch and not child_output.lines:
+      return
+
     branch_info = self.__branches_info[branch]
     if branch_info:
       branch_hash = branch_info.hash
@@ -277,6 +300,11 @@ class BranchMapper(object):
       line.append(behind_string, separator=' ', color=Fore.MAGENTA)
       line.append(back_separator)
 
+    if self.verbosity >= 4:
+      line.append(' (dormant)' if is_dormant_branch else '          ',
+                  separator='  ',
+                  color=Fore.RED)
+
     # The Rietveld issue associated with the branch.
     if self.verbosity >= 2:
       (url, color, status) = ('', '', '') if self.__is_invalid_parent(branch) \
@@ -293,10 +321,9 @@ class BranchMapper(object):
       else:
         line.append('')
 
-    self.output.append(line)
+    output.append(line)
 
-    for child in sorted(self.__parent_map.pop(branch, ())):
-      self.__append_branch(child, depth=depth + 1)
+    output.merge(child_output)
 
 
 def print_desc():
@@ -326,10 +353,13 @@ def main(argv):
     print_desc()
 
   parser = argparse.ArgumentParser()
-  parser.add_argument('-v', action='count', default=0,
+  parser.add_argument('-v',
+                      action='count',
+                      default=0,
                       help=('Pass once to show tracking info, '
                             'twice for hash and review url, '
-                            'thrice for review status'))
+                            'thrice for review status, '
+                            'four times to mark dormant branches'))
   parser.add_argument('--no-color', action='store_true', dest='nocolor',
                       help='Turn off colors.')
   parser.add_argument(
@@ -337,6 +367,10 @@ def main(argv):
       help='The number of jobs to use when retrieving review status')
   parser.add_argument('--show-subject', action='store_true',
                       dest='show_subject', help='Show the commit subject.')
+  parser.add_argument('--hide-dormant',
+                      action='store_true',
+                      dest='hide_dormant',
+                      help='Hides dormant branches.')
 
   opts = parser.parse_args(argv)
 
@@ -345,6 +379,7 @@ def main(argv):
   mapper.output.nocolor = opts.nocolor
   mapper.maxjobs = opts.maxjobs
   mapper.show_subject = opts.show_subject
+  mapper.hide_dormant = opts.hide_dormant
   mapper.start()
   print(mapper.output.as_formatted_string())
   return 0