From 46b21db196260710ed6336a963f1c8aa9f893234 Mon Sep 17 00:00:00 2001 From: Adam Waldenberg Date: Sat, 31 Oct 2015 03:44:00 +0100 Subject: [PATCH] The changes module now supports multiple repositories (See issue #24). Just as before, all other parts of gitinspector currently do not support fetching statistics from multiple repositories and just simply fetch data from the last repository specified. --- gitinspector/changes.py | 42 ++++++++++++++++++++-------- gitinspector/gitinspector.py | 7 ++++- gitinspector/output/changesoutput.py | 5 +--- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/gitinspector/changes.py b/gitinspector/changes.py index 0f7041f..0c0cd20 100644 --- a/gitinspector/changes.py +++ b/gitinspector/changes.py @@ -18,6 +18,7 @@ # along with gitinspector. If not, see . from __future__ import unicode_literals +import bisect import datetime import multiprocessing import os @@ -69,11 +70,15 @@ class Commit(object): self.filediffs = [] commit_line = string.split("|") - if commit_line.__len__() == 4: - self.date = commit_line[0] - self.sha = commit_line[1] - self.author = commit_line[2].strip() - self.email = commit_line[3].strip() + if commit_line.__len__() == 5: + self.timestamp = commit_line[0] + self.date = commit_line[1] + self.sha = commit_line[2] + self.author = commit_line[3].strip() + self.email = commit_line[4].strip() + + def __lt__(self, other): + return self.timestamp.__lt__(other.timestamp) # only used for sorting; we just consider the timestamp. def add_filediff(self, filediff): self.filediffs.append(filediff) @@ -85,12 +90,12 @@ class Commit(object): def get_author_and_email(string): commit_line = string.split("|") - if commit_line.__len__() == 4: - return (commit_line[2].strip(), commit_line[3].strip()) + if commit_line.__len__() == 5: + return (commit_line[3].strip(), commit_line[4].strip()) @staticmethod def is_commit_line(string): - return string.split("|").__len__() == 4 + return string.split("|").__len__() == 5 class AuthorInfo(object): email = None @@ -116,7 +121,7 @@ class ChangesThread(threading.Thread): thread.start() def run(self): - git_log_r = subprocess.Popen(filter(None, ["git", "log", "--reverse", "--pretty=%cd|%H|%aN|%aE", + git_log_r = subprocess.Popen(filter(None, ["git", "log", "--reverse", "--pretty=%ct|%cd|%H|%aN|%aE", "--stat=100000,8192", "--no-merges", "-w", interval.get_since(), interval.get_until(), "--date=short"] + (["-C", "-C", "-M"] if self.hard else []) + [self.first_hash + self.second_hash]), bufsize=1, stdout=subprocess.PIPE).stdout @@ -142,7 +147,7 @@ class ChangesThread(threading.Thread): if Commit.is_commit_line(j) or i is lines[-1]: if found_valid_extension: - commits.append(commit) + bisect.insort(commits, commit) found_valid_extension = False is_filtered = False @@ -206,6 +211,10 @@ class Changes(object): 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() + self.commits = [item for sublist in self.commits for item in sublist] if len(self.commits) > 0: @@ -218,7 +227,18 @@ class Changes(object): int(self.commits[-1].date[8:10])) def __add__(self, other): - pass # TODO + if other == None: + return self + + self.authors.update(other.authors) + self.authors_dateinfo.update(other.authors_dateinfo) + self.authors_by_email.update(other.authors_by_email) + self.emails_by_author.update(other.emails_by_author) + + for commit in other.commits: + bisect.insort(self.commits, commit) + + return self def get_commits(self): return self.commits diff --git a/gitinspector/gitinspector.py b/gitinspector/gitinspector.py index 8c7e768..e7ddf17 100644 --- a/gitinspector/gitinspector.py +++ b/gitinspector/gitinspector.py @@ -58,15 +58,20 @@ class Runner(object): terminal.skip_escapes(not sys.stdout.isatty()) terminal.set_stdout_encoding() previous_directory = os.getcwd() + changes = None for repo in repos: os.chdir(previous_directory) os.chdir(repo) absolute_path = basedir.get_basedir_git() + changes = Changes(self.hard) + changes + + if sys.stdout.isatty() and format.is_interactive_format(): + terminal.clear_row() + os.chdir(absolute_path) format.output_header(absolute_path) - changes = Changes(self.hard) outputable.output(ChangesOutput(changes)) if changes.get_commits(): diff --git a/gitinspector/output/changesoutput.py b/gitinspector/output/changesoutput.py index b982e8e..4e3b380 100644 --- a/gitinspector/output/changesoutput.py +++ b/gitinspector/output/changesoutput.py @@ -26,7 +26,7 @@ from ..localization import N_ from .. import format, gravatar, terminal from .outputable import Outputable -HISTORICAL_INFO_TEXT = N_("The following historical commit information, by author, was found in the repository") +HISTORICAL_INFO_TEXT = N_("The following historical commit information, by author, was found") NO_COMMITED_FILES_TEXT = N_("No commited files with the specified extensions were found") class ChangesOutput(Outputable): @@ -129,9 +129,6 @@ class ChangesOutput(Outputable): print("\t\t\"exception\": \"" + _(NO_COMMITED_FILES_TEXT) + "\"") def output_text(self): - if sys.stdout.isatty() and format.is_interactive_format(): - terminal.clear_row() - authorinfo_list = self.changes.get_authorinfo_list() total_changes = 0.0