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>
changes/49/4654849/3
Orr Bernstein 2 years ago committed by LUCI CQ
parent abbd5858fa
commit b7e16d28f6

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

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

Loading…
Cancel
Save