Skip to content

Commit a56680c

Browse files
Handle git-rev-list and git-ls-tree with empty changesets (ejwa#132, ejwa#115).
If the changeset was empty or filtered with no matching files a bunch of errors would be thrown from git with no proper results being returned back to gitinspector. We now pipe stderr (catching the output) and also check the return code when running these commands.
1 parent 8cff4bd commit a56680c

File tree

3 files changed

+66
-61
lines changed

3 files changed

+66
-61
lines changed

gitinspector/blame.py

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding: utf-8
22
#
3-
# Copyright © 2012-2015 Ejwa Software. All rights reserved.
3+
# Copyright © 2012-2017 Ejwa Software. All rights reserved.
44
#
55
# This file is part of gitinspector.
66
#
@@ -123,40 +123,42 @@ def run(self):
123123
class Blame(object):
124124
def __init__(self, repo, hard, useweeks, changes):
125125
self.blames = {}
126-
ls_tree_r = subprocess.Popen(["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1,
127-
stdout=subprocess.PIPE).stdout
128-
lines = ls_tree_r.readlines()
129-
ls_tree_r.close()
130-
131-
progress_text = _(PROGRESS_TEXT)
132-
if repo != None:
133-
progress_text = "[%s] " % repo.name + progress_text
134-
135-
for i, row in enumerate(lines):
136-
row = row.strip().decode("unicode_escape", "ignore")
137-
row = row.encode("latin-1", "replace")
138-
row = row.decode("utf-8", "replace").strip("\"").strip("'").strip()
139-
140-
if FileDiff.get_extension(row) in extensions.get_located() and FileDiff.is_valid_extension(row) and not \
141-
filtering.set_filtered(FileDiff.get_filename(row)):
142-
blame_command = filter(None, ["git", "blame", "--line-porcelain", "-w"] + \
143-
(["-C", "-C", "-M"] if hard else []) +
144-
[interval.get_since(), interval.get_ref(), "--", row])
145-
thread = BlameThread(useweeks, changes, blame_command, FileDiff.get_extension(row),
146-
self.blames, row.strip())
147-
thread.daemon = True
148-
thread.start()
149-
150-
if format.is_interactive_format():
151-
terminal.output_progress(progress_text, i, len(lines))
152-
153-
# Make sure all threads have completed.
154-
for i in range(0, NUM_THREADS):
155-
__thread_lock__.acquire()
156-
157-
# We also have to release them for future use.
158-
for i in range(0, NUM_THREADS):
159-
__thread_lock__.release()
126+
ls_tree_p = subprocess.Popen(["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1,
127+
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
128+
lines = ls_tree_p.communicate()[0].splitlines()
129+
ls_tree_p.stdout.close()
130+
131+
if ls_tree_p.returncode == 0:
132+
progress_text = _(PROGRESS_TEXT)
133+
134+
if repo != None:
135+
progress_text = "[%s] " % repo.name + progress_text
136+
137+
for i, row in enumerate(lines):
138+
row = row.strip().decode("unicode_escape", "ignore")
139+
row = row.encode("latin-1", "replace")
140+
row = row.decode("utf-8", "replace").strip("\"").strip("'").strip()
141+
142+
if FileDiff.get_extension(row) in extensions.get_located() and \
143+
FileDiff.is_valid_extension(row) and not filtering.set_filtered(FileDiff.get_filename(row)):
144+
blame_command = filter(None, ["git", "blame", "--line-porcelain", "-w"] + \
145+
(["-C", "-C", "-M"] if hard else []) +
146+
[interval.get_since(), interval.get_ref(), "--", row])
147+
thread = BlameThread(useweeks, changes, blame_command, FileDiff.get_extension(row),
148+
self.blames, row.strip())
149+
thread.daemon = True
150+
thread.start()
151+
152+
if format.is_interactive_format():
153+
terminal.output_progress(progress_text, i, len(lines))
154+
155+
# Make sure all threads have completed.
156+
for i in range(0, NUM_THREADS):
157+
__thread_lock__.acquire()
158+
159+
# We also have to release them for future use.
160+
for i in range(0, NUM_THREADS):
161+
__thread_lock__.release()
160162

161163
def __iadd__(self, other):
162164
try:

gitinspector/changes.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding: utf-8
22
#
3-
# Copyright © 2012-2015 Ejwa Software. All rights reserved.
3+
# Copyright © 2012-2017 Ejwa Software. All rights reserved.
44
#
55
# This file is part of gitinspector.
66
#
@@ -183,13 +183,13 @@ class Changes(object):
183183

184184
def __init__(self, repo, hard):
185185
self.commits = []
186-
git_log_hashes_r = subprocess.Popen(filter(None, ["git", "rev-list", "--reverse", "--no-merges",
187-
interval.get_since(), interval.get_until(), "HEAD"]), bufsize=1,
188-
stdout=subprocess.PIPE).stdout
189-
lines = git_log_hashes_r.readlines()
190-
git_log_hashes_r.close()
186+
git_rev_list_p = subprocess.Popen(filter(None, ["git", "rev-list", "--reverse", "--no-merges",
187+
interval.get_since(), interval.get_until(), "HEAD"]), bufsize=1,
188+
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
189+
lines = git_rev_list_p.communicate()[0].splitlines()
190+
git_rev_list_p.stdout.close()
191191

192-
if len(lines) > 0:
192+
if git_rev_list_p.returncode == 0 and len(lines) > 0:
193193
progress_text = _(PROGRESS_TEXT)
194194
if repo != None:
195195
progress_text = "[%s] " % repo.name + progress_text

gitinspector/metrics.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding: utf-8
22
#
3-
# Copyright © 2012-2015 Ejwa Software. All rights reserved.
3+
# Copyright © 2012-2017 Ejwa Software. All rights reserved.
44
#
55
# This file is part of gitinspector.
66
#
@@ -44,30 +44,33 @@ def __init__(self):
4444
self.cyclomatic_complexity = {}
4545
self.cyclomatic_complexity_density = {}
4646

47-
ls_tree_r = subprocess.Popen(["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1,
48-
stdout=subprocess.PIPE).stdout
47+
ls_tree_p = subprocess.Popen(["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1,
48+
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
49+
lines = ls_tree_p.communicate()[0].splitlines()
50+
ls_tree_p.stdout.close()
4951

50-
for i in ls_tree_r.readlines():
51-
i = i.strip().decode("unicode_escape", "ignore")
52-
i = i.encode("latin-1", "replace")
53-
i = i.decode("utf-8", "replace").strip("\"").strip("'").strip()
52+
if ls_tree_p.returncode == 0:
53+
for i in lines:
54+
i = i.strip().decode("unicode_escape", "ignore")
55+
i = i.encode("latin-1", "replace")
56+
i = i.decode("utf-8", "replace").strip("\"").strip("'").strip()
5457

55-
if FileDiff.is_valid_extension(i) and not filtering.set_filtered(FileDiff.get_filename(i)):
56-
file_r = subprocess.Popen(["git", "show", interval.get_ref() + ":{0}".format(i.strip())],
57-
bufsize=1, stdout=subprocess.PIPE).stdout.readlines()
58+
if FileDiff.is_valid_extension(i) and not filtering.set_filtered(FileDiff.get_filename(i)):
59+
file_r = subprocess.Popen(["git", "show", interval.get_ref() + ":{0}".format(i.strip())],
60+
bufsize=1, stdout=subprocess.PIPE).stdout.readlines()
5861

59-
extension = FileDiff.get_extension(i)
60-
lines = MetricsLogic.get_eloc(file_r, extension)
61-
cycc = MetricsLogic.get_cyclomatic_complexity(file_r, extension)
62+
extension = FileDiff.get_extension(i)
63+
lines = MetricsLogic.get_eloc(file_r, extension)
64+
cycc = MetricsLogic.get_cyclomatic_complexity(file_r, extension)
6265

63-
if __metric_eloc__.get(extension, None) != None and __metric_eloc__[extension] < lines:
64-
self.eloc[i.strip()] = lines
66+
if __metric_eloc__.get(extension, None) != None and __metric_eloc__[extension] < lines:
67+
self.eloc[i.strip()] = lines
6568

66-
if METRIC_CYCLOMATIC_COMPLEXITY_THRESHOLD < cycc:
67-
self.cyclomatic_complexity[i.strip()] = cycc
69+
if METRIC_CYCLOMATIC_COMPLEXITY_THRESHOLD < cycc:
70+
self.cyclomatic_complexity[i.strip()] = cycc
6871

69-
if lines > 0 and METRIC_CYCLOMATIC_COMPLEXITY_DENSITY_THRESHOLD < cycc / float(lines):
70-
self.cyclomatic_complexity_density[i.strip()] = cycc / float(lines)
72+
if lines > 0 and METRIC_CYCLOMATIC_COMPLEXITY_DENSITY_THRESHOLD < cycc / float(lines):
73+
self.cyclomatic_complexity_density[i.strip()] = cycc / float(lines)
7174

7275
def __iadd__(self, other):
7376
try:

0 commit comments

Comments
 (0)