From 7b586f231ba116d16b89639e04d940ae008ffff2 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 23 Feb 2021 18:38:39 -0500 Subject: [PATCH] sync: capture all git output by default The default sync output should show a progress bar only for successful commands, and the error output for any commands that fail. Implement that policy here. Bug: https://crbug.com/gerrit/11293 Change-Id: I85716032201b6e2b45df876b07dd79cb2c1447a5 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/297905 Reviewed-by: Michael Mortensen Tested-by: Mike Frysinger --- project.py | 21 +++++++++++++++------ subcmds/sync.py | 7 +++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/project.py b/project.py index de7bbbc9..b81c10a1 100644 --- a/project.py +++ b/project.py @@ -1039,6 +1039,7 @@ class Project(object): def Sync_NetworkHalf(self, quiet=False, verbose=False, + output_redir=None, is_new=None, current_branch_only=False, force_sync=False, @@ -1126,8 +1127,9 @@ class Project(object): (ID_RE.match(self.revisionExpr) and self._CheckForImmutableRevision())): if not self._RemoteFetch( - initial=is_new, quiet=quiet, verbose=verbose, alt_dir=alt_dir, - current_branch_only=current_branch_only, + initial=is_new, + quiet=quiet, verbose=verbose, output_redir=output_redir, + alt_dir=alt_dir, current_branch_only=current_branch_only, tags=tags, prune=prune, depth=depth, submodules=submodules, force_sync=force_sync, clone_filter=clone_filter, retry_fetches=retry_fetches): @@ -1139,7 +1141,11 @@ class Project(object): alternates_file = os.path.join(self.gitdir, 'objects/info/alternates') if os.path.exists(alternates_file): cmd = ['repack', '-a', '-d'] - if GitCommand(self, cmd, bare=True).Wait() != 0: + p = GitCommand(self, cmd, bare=True, capture_stdout=bool(output_redir), + merge_output=bool(output_redir)) + if p.stdout and output_redir: + buf.write(p.stdout) + if p.Wait() != 0: return False platform_utils.remove(alternates_file) @@ -1951,6 +1957,7 @@ class Project(object): initial=False, quiet=False, verbose=False, + output_redir=None, alt_dir=None, tags=True, prune=False, @@ -2128,7 +2135,9 @@ class Project(object): ok = prune_tried = False for try_n in range(retry_fetches): gitcmd = GitCommand(self, cmd, bare=True, ssh_proxy=ssh_proxy, - merge_output=True, capture_stdout=quiet) + merge_output=True, capture_stdout=quiet or bool(output_redir)) + if gitcmd.stdout and not quiet and output_redir: + output_redir.write(gitcmd.stdout) ret = gitcmd.Wait() if ret == 0: ok = True @@ -2170,7 +2179,7 @@ class Project(object): # Git died with a signal, exit immediately break if not verbose: - print('%s:\n%s' % (self.name, gitcmd.stdout), file=sys.stderr) + print('\n%s:\n%s' % (self.name, gitcmd.stdout), file=sys.stderr) time.sleep(random.randint(30, 45)) if initial: @@ -2189,7 +2198,7 @@ class Project(object): # Sync the current branch only with depth set to None. # We always pass depth=None down to avoid infinite recursion. return self._RemoteFetch( - name=name, quiet=quiet, verbose=verbose, + name=name, quiet=quiet, verbose=verbose, output_redir=output_redir, current_branch_only=current_branch_only and depth, initial=False, alt_dir=alt_dir, depth=None, clone_filter=clone_filter) diff --git a/subcmds/sync.py b/subcmds/sync.py index b1b6a6ef..d1b631ae 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py @@ -13,6 +13,7 @@ # limitations under the License. import http.cookiejar as cookielib +import io import json import netrc from optparse import SUPPRESS_HELP @@ -354,6 +355,7 @@ later is required to fix a server side protocol bug. # - We always make sure we unlock the lock if we locked it. start = time.time() success = False + buf = io.StringIO() with lock: pm.start(project.name) try: @@ -361,6 +363,7 @@ later is required to fix a server side protocol bug. success = project.Sync_NetworkHalf( quiet=opt.quiet, verbose=opt.verbose, + output_redir=buf, current_branch_only=opt.current_branch_only, force_sync=opt.force_sync, clone_bundle=opt.clone_bundle, @@ -376,6 +379,10 @@ later is required to fix a server side protocol bug. lock.acquire() did_lock = True + output = buf.getvalue() + if opt.verbose and output: + pm.update(inc=0, msg=output.rstrip()) + if not success: err_event.set() print('error: Cannot fetch %s from %s'