summaryrefslogtreecommitdiffstats
path: root/project.py
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2021-02-16 17:08:35 -0500
committerMike Frysinger <vapier@google.com>2021-02-18 03:54:30 +0000
commit84230009ee4282b947482f0d4fc4fe9e9ebc9e01 (patch)
treefd38d44f98ab05a2762fe7a3b0e80b60775640f5 /project.py
parentf37b9827a966258a0adc2012a7c5c89cf89e4a0f (diff)
downloadgit-repo-84230009ee4282b947482f0d4fc4fe9e9ebc9e01.tar.gz
project: make diff tools synchronous
These are the only users in the tree that process the output as it's produced. All others capture all the output first and then process the results. However, these functions still don't fully return until it's finished processing, and these funcs are in turn used in other synchronous code paths. So it's unclear whether anyone will notice that it's slightly slower or less interactive. Let's try it out and see if users report issues. This will allow us to simplify our custom GitCommand code and move it over to Python's subprocess.run, and will help fix interleaved output when running multiple commands in parallel (e.g. `repo diff -j8`). Change-Id: Ida16fafc47119d30a629a8783babeba890515de0 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/297144 Tested-by: Mike Frysinger <vapier@google.com> Reviewed-by: Jonathan Nieder <jrn@google.com>
Diffstat (limited to 'project.py')
-rw-r--r--project.py96
1 files changed, 44 insertions, 52 deletions
diff --git a/project.py b/project.py
index a9deda42..86f41f22 100644
--- a/project.py
+++ b/project.py
@@ -849,6 +849,7 @@ class Project(object):
849 cmd, 849 cmd,
850 capture_stdout=True, 850 capture_stdout=True,
851 capture_stderr=True) 851 capture_stderr=True)
852 p.Wait()
852 except GitError as e: 853 except GitError as e:
853 out.nl() 854 out.nl()
854 out.project('project %s/' % self.relpath) 855 out.project('project %s/' % self.relpath)
@@ -856,16 +857,11 @@ class Project(object):
856 out.fail('%s', str(e)) 857 out.fail('%s', str(e))
857 out.nl() 858 out.nl()
858 return False 859 return False
859 has_diff = False 860 if p.stdout:
860 for line in p.process.stdout: 861 out.nl()
861 if not hasattr(line, 'encode'): 862 out.project('project %s/' % self.relpath)
862 line = line.decode() 863 out.nl()
863 if not has_diff: 864 out.write(p.stdout)
864 out.nl()
865 out.project('project %s/' % self.relpath)
866 out.nl()
867 has_diff = True
868 print(line[:-1])
869 return p.Wait() == 0 865 return p.Wait() == 0
870 866
871# Publish / Upload ## 867# Publish / Upload ##
@@ -2861,48 +2857,44 @@ class Project(object):
2861 bare=False, 2857 bare=False,
2862 capture_stdout=True, 2858 capture_stdout=True,
2863 capture_stderr=True) 2859 capture_stderr=True)
2864 try: 2860 p.Wait()
2865 out = p.process.stdout.read() 2861 r = {}
2866 if not hasattr(out, 'encode'): 2862 out = p.stdout
2867 out = out.decode() 2863 if out:
2868 r = {} 2864 out = iter(out[:-1].split('\0'))
2869 if out: 2865 while out:
2870 out = iter(out[:-1].split('\0')) 2866 try:
2871 while out: 2867 info = next(out)
2872 try: 2868 path = next(out)
2873 info = next(out) 2869 except StopIteration:
2874 path = next(out) 2870 break
2875 except StopIteration: 2871
2876 break 2872 class _Info(object):
2877 2873
2878 class _Info(object): 2874 def __init__(self, path, omode, nmode, oid, nid, state):
2879 2875 self.path = path
2880 def __init__(self, path, omode, nmode, oid, nid, state): 2876 self.src_path = None
2881 self.path = path 2877 self.old_mode = omode
2882 self.src_path = None 2878 self.new_mode = nmode
2883 self.old_mode = omode 2879 self.old_id = oid
2884 self.new_mode = nmode 2880 self.new_id = nid
2885 self.old_id = oid 2881
2886 self.new_id = nid 2882 if len(state) == 1:
2887 2883 self.status = state
2888 if len(state) == 1: 2884 self.level = None
2889 self.status = state 2885 else:
2890 self.level = None 2886 self.status = state[:1]
2891 else: 2887 self.level = state[1:]
2892 self.status = state[:1] 2888 while self.level.startswith('0'):
2893 self.level = state[1:] 2889 self.level = self.level[1:]
2894 while self.level.startswith('0'): 2890
2895 self.level = self.level[1:] 2891 info = info[1:].split(' ')
2896 2892 info = _Info(path, *info)
2897 info = info[1:].split(' ') 2893 if info.status in ('R', 'C'):
2898 info = _Info(path, *info) 2894 info.src_path = info.path
2899 if info.status in ('R', 'C'): 2895 info.path = next(out)
2900 info.src_path = info.path 2896 r[info.path] = info
2901 info.path = next(out) 2897 return r
2902 r[info.path] = info
2903 return r
2904 finally:
2905 p.Wait()
2906 2898
2907 def GetDotgitPath(self, subpath=None): 2899 def GetDotgitPath(self, subpath=None):
2908 """Return the full path to the .git dir. 2900 """Return the full path to the .git dir.