Handle git-rev-list and git-ls-tree with empty changesets (#132, #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.
This commit is contained in:
Adam Waldenberg 2017-05-13 15:30:32 +02:00
parent 8cff4bd208
commit a56680c4b4
3 changed files with 60 additions and 55 deletions

View file

@ -1,6 +1,6 @@
# coding: utf-8
#
# Copyright © 2012-2015 Ejwa Software. All rights reserved.
# Copyright © 2012-2017 Ejwa Software. All rights reserved.
#
# This file is part of gitinspector.
#
@ -123,40 +123,42 @@ PROGRESS_TEXT = N_("Checking how many rows belong to each author (2 of 2): {0:.0
class Blame(object):
def __init__(self, repo, hard, useweeks, changes):
self.blames = {}
ls_tree_r = subprocess.Popen(["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1,
stdout=subprocess.PIPE).stdout
lines = ls_tree_r.readlines()
ls_tree_r.close()
ls_tree_p = subprocess.Popen(["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
lines = ls_tree_p.communicate()[0].splitlines()
ls_tree_p.stdout.close()
progress_text = _(PROGRESS_TEXT)
if repo != None:
progress_text = "[%s] " % repo.name + progress_text
if ls_tree_p.returncode == 0:
progress_text = _(PROGRESS_TEXT)
for i, row in enumerate(lines):
row = row.strip().decode("unicode_escape", "ignore")
row = row.encode("latin-1", "replace")
row = row.decode("utf-8", "replace").strip("\"").strip("'").strip()
if repo != None:
progress_text = "[%s] " % repo.name + progress_text
if FileDiff.get_extension(row) in extensions.get_located() and FileDiff.is_valid_extension(row) and not \
filtering.set_filtered(FileDiff.get_filename(row)):
blame_command = filter(None, ["git", "blame", "--line-porcelain", "-w"] + \
(["-C", "-C", "-M"] if hard else []) +
[interval.get_since(), interval.get_ref(), "--", row])
thread = BlameThread(useweeks, changes, blame_command, FileDiff.get_extension(row),
self.blames, row.strip())
thread.daemon = True
thread.start()
for i, row in enumerate(lines):
row = row.strip().decode("unicode_escape", "ignore")
row = row.encode("latin-1", "replace")
row = row.decode("utf-8", "replace").strip("\"").strip("'").strip()
if format.is_interactive_format():
terminal.output_progress(progress_text, i, len(lines))
if FileDiff.get_extension(row) in extensions.get_located() and \
FileDiff.is_valid_extension(row) and not filtering.set_filtered(FileDiff.get_filename(row)):
blame_command = filter(None, ["git", "blame", "--line-porcelain", "-w"] + \
(["-C", "-C", "-M"] if hard else []) +
[interval.get_since(), interval.get_ref(), "--", row])
thread = BlameThread(useweeks, changes, blame_command, FileDiff.get_extension(row),
self.blames, row.strip())
thread.daemon = True
thread.start()
# Make sure all threads have completed.
for i in range(0, NUM_THREADS):
__thread_lock__.acquire()
if format.is_interactive_format():
terminal.output_progress(progress_text, i, len(lines))
# We also have to release them for future use.
for i in range(0, NUM_THREADS):
__thread_lock__.release()
# Make sure all threads have completed.
for i in range(0, NUM_THREADS):
__thread_lock__.acquire()
# We also have to release them for future use.
for i in range(0, NUM_THREADS):
__thread_lock__.release()
def __iadd__(self, other):
try:

View file

@ -1,6 +1,6 @@
# coding: utf-8
#
# Copyright © 2012-2015 Ejwa Software. All rights reserved.
# Copyright © 2012-2017 Ejwa Software. All rights reserved.
#
# This file is part of gitinspector.
#
@ -183,13 +183,13 @@ class Changes(object):
def __init__(self, repo, hard):
self.commits = []
git_log_hashes_r = subprocess.Popen(filter(None, ["git", "rev-list", "--reverse", "--no-merges",
interval.get_since(), interval.get_until(), "HEAD"]), bufsize=1,
stdout=subprocess.PIPE).stdout
lines = git_log_hashes_r.readlines()
git_log_hashes_r.close()
git_rev_list_p = subprocess.Popen(filter(None, ["git", "rev-list", "--reverse", "--no-merges",
interval.get_since(), interval.get_until(), "HEAD"]), bufsize=1,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
lines = git_rev_list_p.communicate()[0].splitlines()
git_rev_list_p.stdout.close()
if len(lines) > 0:
if git_rev_list_p.returncode == 0 and len(lines) > 0:
progress_text = _(PROGRESS_TEXT)
if repo != None:
progress_text = "[%s] " % repo.name + progress_text

View file

@ -1,6 +1,6 @@
# coding: utf-8
#
# Copyright © 2012-2015 Ejwa Software. All rights reserved.
# Copyright © 2012-2017 Ejwa Software. All rights reserved.
#
# This file is part of gitinspector.
#
@ -44,30 +44,33 @@ class MetricsLogic(object):
self.cyclomatic_complexity = {}
self.cyclomatic_complexity_density = {}
ls_tree_r = subprocess.Popen(["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1,
stdout=subprocess.PIPE).stdout
ls_tree_p = subprocess.Popen(["git", "ls-tree", "--name-only", "-r", interval.get_ref()], bufsize=1,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
lines = ls_tree_p.communicate()[0].splitlines()
ls_tree_p.stdout.close()
for i in ls_tree_r.readlines():
i = i.strip().decode("unicode_escape", "ignore")
i = i.encode("latin-1", "replace")
i = i.decode("utf-8", "replace").strip("\"").strip("'").strip()
if ls_tree_p.returncode == 0:
for i in lines:
i = i.strip().decode("unicode_escape", "ignore")
i = i.encode("latin-1", "replace")
i = i.decode("utf-8", "replace").strip("\"").strip("'").strip()
if FileDiff.is_valid_extension(i) and not filtering.set_filtered(FileDiff.get_filename(i)):
file_r = subprocess.Popen(["git", "show", interval.get_ref() + ":{0}".format(i.strip())],
bufsize=1, stdout=subprocess.PIPE).stdout.readlines()
if FileDiff.is_valid_extension(i) and not filtering.set_filtered(FileDiff.get_filename(i)):
file_r = subprocess.Popen(["git", "show", interval.get_ref() + ":{0}".format(i.strip())],
bufsize=1, stdout=subprocess.PIPE).stdout.readlines()
extension = FileDiff.get_extension(i)
lines = MetricsLogic.get_eloc(file_r, extension)
cycc = MetricsLogic.get_cyclomatic_complexity(file_r, extension)
extension = FileDiff.get_extension(i)
lines = MetricsLogic.get_eloc(file_r, extension)
cycc = MetricsLogic.get_cyclomatic_complexity(file_r, extension)
if __metric_eloc__.get(extension, None) != None and __metric_eloc__[extension] < lines:
self.eloc[i.strip()] = lines
if __metric_eloc__.get(extension, None) != None and __metric_eloc__[extension] < lines:
self.eloc[i.strip()] = lines
if METRIC_CYCLOMATIC_COMPLEXITY_THRESHOLD < cycc:
self.cyclomatic_complexity[i.strip()] = cycc
if METRIC_CYCLOMATIC_COMPLEXITY_THRESHOLD < cycc:
self.cyclomatic_complexity[i.strip()] = cycc
if lines > 0 and METRIC_CYCLOMATIC_COMPLEXITY_DENSITY_THRESHOLD < cycc / float(lines):
self.cyclomatic_complexity_density[i.strip()] = cycc / float(lines)
if lines > 0 and METRIC_CYCLOMATIC_COMPLEXITY_DENSITY_THRESHOLD < cycc / float(lines):
self.cyclomatic_complexity_density[i.strip()] = cycc / float(lines)
def __iadd__(self, other):
try: