summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2021-02-16 18:18:01 -0500
committerMike Frysinger <vapier@google.com>2021-02-23 00:31:27 +0000
commit69b4a9cf216f4ffcb69ea2c39ebd6a01b2d0fec9 (patch)
treeb2049f041435fc487a9d1195c602150d3e712678
parentfbab6065d44072d33b2fbe61f604f24397ea2de4 (diff)
downloadgit-repo-69b4a9cf216f4ffcb69ea2c39ebd6a01b2d0fec9.tar.gz
diff: add --jobs support
Use multiprocessing to run diff in parallel. Change-Id: I61e973d9c2cde039d5eebe8d0fe8bb63171ef447 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/297483 Tested-by: Mike Frysinger <vapier@google.com> Reviewed-by: Chris Mcdonald <cjmcdonald@google.com>
-rw-r--r--project.py4
-rw-r--r--subcmds/diff.py42
2 files changed, 41 insertions, 5 deletions
diff --git a/project.py b/project.py
index 52a77f1e..da67c363 100644
--- a/project.py
+++ b/project.py
@@ -832,10 +832,12 @@ class Project(object):
832 832
833 return 'DIRTY' 833 return 'DIRTY'
834 834
835 def PrintWorkTreeDiff(self, absolute_paths=False): 835 def PrintWorkTreeDiff(self, absolute_paths=False, output_redir=None):
836 """Prints the status of the repository to stdout. 836 """Prints the status of the repository to stdout.
837 """ 837 """
838 out = DiffColoring(self.config) 838 out = DiffColoring(self.config)
839 if output_redir:
840 out.redirect(output_redir)
839 cmd = ['diff'] 841 cmd = ['diff']
840 if out.is_on: 842 if out.is_on:
841 cmd.append('--color') 843 cmd.append('--color')
diff --git a/subcmds/diff.py b/subcmds/diff.py
index c987bf23..81868176 100644
--- a/subcmds/diff.py
+++ b/subcmds/diff.py
@@ -12,7 +12,11 @@
12# See the License for the specific language governing permissions and 12# See the License for the specific language governing permissions and
13# limitations under the License. 13# limitations under the License.
14 14
15from command import PagedCommand 15import functools
16import io
17import multiprocessing
18
19from command import DEFAULT_LOCAL_JOBS, PagedCommand, WORKER_BATCH_SIZE
16 20
17 21
18class Diff(PagedCommand): 22class Diff(PagedCommand):
@@ -25,15 +29,45 @@ The -u option causes '%prog' to generate diff output with file paths
25relative to the repository root, so the output can be applied 29relative to the repository root, so the output can be applied
26to the Unix 'patch' command. 30to the Unix 'patch' command.
27""" 31"""
32 PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
28 33
29 def _Options(self, p): 34 def _Options(self, p):
35 super()._Options(p)
30 p.add_option('-u', '--absolute', 36 p.add_option('-u', '--absolute',
31 dest='absolute', action='store_true', 37 dest='absolute', action='store_true',
32 help='Paths are relative to the repository root') 38 help='Paths are relative to the repository root')
33 39
40 def _DiffHelper(self, absolute, project):
41 """Obtains the diff for a specific project.
42
43 Args:
44 absolute: Paths are relative to the root.
45 project: Project to get status of.
46
47 Returns:
48 The status of the project.
49 """
50 buf = io.StringIO()
51 ret = project.PrintWorkTreeDiff(absolute, output_redir=buf)
52 return (ret, buf.getvalue())
53
34 def Execute(self, opt, args): 54 def Execute(self, opt, args):
35 ret = 0 55 ret = 0
36 for project in self.GetProjects(args): 56 all_projects = self.GetProjects(args)
37 if not project.PrintWorkTreeDiff(opt.absolute): 57
38 ret = 1 58 # NB: Multiprocessing is heavy, so don't spin it up for one job.
59 if len(all_projects) == 1 or opt.jobs == 1:
60 for project in all_projects:
61 if not project.PrintWorkTreeDiff(opt.absolute):
62 ret = 1
63 else:
64 with multiprocessing.Pool(opt.jobs) as pool:
65 states = pool.imap(functools.partial(self._DiffHelper, opt.absolute),
66 all_projects, WORKER_BATCH_SIZE)
67 for (state, output) in states:
68 if output:
69 print(output, end='')
70 if not state:
71 ret = 1
72
39 return ret 73 return ret