From 662cd3fa63ec5593c5a55b02ecb0a92d58135ec9 Mon Sep 17 00:00:00 2001 From: Adam Waldenberg Date: Mon, 22 Jul 2013 05:51:56 +0200 Subject: [PATCH] Fixed some behavior that got broken with the implementation of gravatars. Previously, gitinspector always tried to merge authors with the same name (independently of the email). This behavior tends to (for the most part) help in projects missing a .mailmap file. Often; authors commit under the same name, but with different emails on different computers (if they for example have a work email on their office desktop). Whenever different e-mail addresses are used by an author; gitinspector will use the last email it finds and will generate a gravatar from that email address. This behavior was chosen because authors mostly do not tend to create a gravatar image for their old email accounts (but often have one in their newer ones). --- gitinspector/blame.py | 19 ++++++++++--------- gitinspector/changes.py | 26 +++++++++++++------------- gitinspector/timeline.py | 27 +++++++++++++-------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/gitinspector/blame.py b/gitinspector/blame.py index 4278128..1b861d8 100644 --- a/gitinspector/blame.py +++ b/gitinspector/blame.py @@ -93,7 +93,7 @@ class Blame: if FileDiff.is_valid_extension(row) and not filtering.set_filtered(FileDiff.get_filename(row)): if not missing.add(row): - blame_string = "git blame -e -w {0} ".format("-C -C -M" if hard else "") + \ + blame_string = "git blame -w {0} ".format("-C -C -M" if hard else "") + \ interval.get_since() + interval.get_ref() + " -- \"" + row + "\"" thread = BlameThread(blame_string, FileDiff.get_extension(row), self.blames, row.strip()) thread.daemon = True @@ -173,12 +173,12 @@ class BlameOutput(Outputable): for i, entry in enumerate(blames): work_percentage = str("{0:.2f}".format(100.0 * entry[1].rows / total_blames)) - authorname = self.changes.get_authorname_from_email(entry[0]) + author_email = self.changes.get_author_email(entry[0]) blame_xml += "" if i % 2 == 1 else ">") if format.get_selected() == "html": - blame_xml += "{1}".format(gravatar.get_url(entry[0]), authorname) + blame_xml += "{1}".format(gravatar.get_url(author_email), entry[0]) else: blame_xml += "" + authorname + "" @@ -186,7 +186,7 @@ class BlameOutput(Outputable): blame_xml += "" + "{0:.2f}".format(100.0 * entry[1].comments / entry[1].rows) + "" blame_xml += "" + work_percentage + "" blame_xml += "" - chart_data += "{{label: \"{0}\", data: {1}}}".format(authorname, work_percentage) + chart_data += "{{label: \"{0}\", data: {1}}}".format(entry[0], work_percentage) if blames[-1] != entry: chart_data += ", " @@ -221,9 +221,9 @@ class BlameOutput(Outputable): print(textwrap.fill(_(BLAME_INFO_TEXT) + ":", width=terminal.get_size()[0]) + "\n") terminal.printb(_("Author").ljust(21) + _("Rows").rjust(10) + _("% in comments").rjust(20)) + for i in sorted(__blame__.get_summed_blames().items()): - authorname = self.changes.get_authorname_from_email(i[0]) - print(authorname.ljust(20)[0:20], end=" ") + print(i[0].ljust(20)[0:20], end=" ") print(str(i[1].rows).rjust(10), end=" ") print("{0:.2f}".format(100.0 * i[1].comments / i[1].rows).rjust(19)) @@ -234,9 +234,10 @@ class BlameOutput(Outputable): blame_xml = "" for i in sorted(__blame__.get_summed_blames().items()): - authorname = self.changes.get_authorname_from_email(i[0]) - name_xml = "\t\t\t\t" + authorname + "\n" - gravatar_xml = "\t\t\t\t" + gravatar.get_url(i[0]) + "\n" + author_email = self.changes.get_author_email(i[0]) + + name_xml = "\t\t\t\t" + i[0] + "\n" + gravatar_xml = "\t\t\t\t" + gravatar.get_url(author_email) + "\n" rows_xml = "\t\t\t\t" + str(i[1].rows) + "\n" percentage_in_comments_xml = ("\t\t\t\t" + "{0:.2f}".format(100.0 * i[1].comments / i[1].rows) + "\n") diff --git a/gitinspector/changes.py b/gitinspector/changes.py index f25dfa7..fe45295 100644 --- a/gitinspector/changes.py +++ b/gitinspector/changes.py @@ -85,6 +85,7 @@ class Commit: return string.split("|").__len__() == 4 class AuthorInfo: + email = None insertions = 0 deletions = 0 commits = 0 @@ -141,29 +142,28 @@ class Changes: authors[key].insertions += j.insertions authors[key].deletions += j.deletions + authors[key].email = commit.email + def get_authorinfo_list(self): if not self.authors: for i in self.commits: - Changes.__modify_authorinfo__(self.authors, (i.author, i.email), i) + Changes.__modify_authorinfo__(self.authors, i.author, i) return self.authors def get_authordateinfo_list(self): if not self.authors_dateinfo: for i in self.commits: - Changes.__modify_authorinfo__(self.authors_dateinfo, (i.date, i.author, i.email), i) + Changes.__modify_authorinfo__(self.authors_dateinfo, (i.date, i.author), i) + self.authors_dateinfo[(i.date, i.author)].email = self.get_authorinfo_list()[i.author].email return self.authors_dateinfo - def get_authorname_from_email(self, email): + def get_author_email(self, name): if not self.authors: - get_authorinfo_list(self) + self.get_authorinfo_list() - for author in self.authors: - if author[1] == email: - return author[0] - - return "Unknown" + return self.authors.get(name).email __changes__ = None @@ -205,7 +205,7 @@ class ChangesOutput(Outputable): changes_xml += "" if i % 2 == 1 else ">") if format.get_selected() == "html": - changes_xml += "{1}".format(gravatar.get_url(entry[1]), entry[0]) + changes_xml += "{1}".format(gravatar.get_url(authorinfo.email), entry) else: changes_xml += "" + entry[0] + "" @@ -214,7 +214,7 @@ class ChangesOutput(Outputable): changes_xml += "" + str(authorinfo.deletions) + "" changes_xml += "" + "{0:.2f}".format(percentage) + "" changes_xml += "" - chart_data += "{{label: \"{0}\", data: {1}}}".format(entry[0], "{0:.2f}".format(percentage)) + chart_data += "{{label: \"{0}\", data: {1}}}".format(entry, "{0:.2f}".format(percentage)) if sorted(authorinfo_list)[-1] != entry: chart_data += ", " @@ -283,8 +283,8 @@ class ChangesOutput(Outputable): for i in sorted(authorinfo_list): authorinfo = authorinfo_list.get(i) percentage = 0 if total_changes == 0 else (authorinfo.insertions + authorinfo.deletions) / total_changes * 100 - name_xml = "\t\t\t\t" + i[0] + "\n" - gravatar_xml = "\t\t\t\t" + gravatar.get_url(i[1]) + "\n" + name_xml = "\t\t\t\t" + i + "\n" + gravatar_xml = "\t\t\t\t" + gravatar.get_url(authorinfo.email) + "\n" commits_xml = "\t\t\t\t" + str(authorinfo.commits) + "\n" insertions_xml = "\t\t\t\t" + str(authorinfo.insertions) + "\n" deletions_xml = "\t\t\t\t" + str(authorinfo.deletions) + "\n" diff --git a/gitinspector/timeline.py b/gitinspector/timeline.py index 5919a6f..d372b20 100644 --- a/gitinspector/timeline.py +++ b/gitinspector/timeline.py @@ -39,9 +39,9 @@ class TimelineData: if useweeks: yearweek = datetime.date(int(i[0][0][0:4]), int(i[0][0][5:7]), int(i[0][0][8:10])).isocalendar() - key = ((i[0][1], i[0][2]), str(yearweek[0]) + "W" + "{0:02d}".format(yearweek[1])) + key = (i[0][1], str(yearweek[0]) + "W" + "{0:02d}".format(yearweek[1])) else: - key = ((i[0][1], i[0][2]), i[0][0][0:7]) + key = (i[0][1], i[0][0][0:7]) if self.entries.get(key, None) == None: self.entries[key] = i[1] @@ -54,7 +54,7 @@ class TimelineData: total_deletions = 0 for author in self.get_authors(): - entry = self.entries.get((author, period), None) + entry = self.entries.get((author[0], period), None) if entry != None: total_insertions += entry.insertions total_deletions += entry.deletions @@ -69,7 +69,7 @@ class TimelineData: return self.total_changes_by_period[period] def get_authors(self): - return sorted(set([i[0] for i in self.entries])) + return sorted(set([(i[0][0], i[1].email) for i in self.entries.items()])) def get_author_signs_in_period(self, author, period, multiplier): authorinfo = self.entries.get((author, period), None) @@ -118,13 +118,13 @@ def __output_row__text__(timeline_data, periods, names): print(terminal.__normal__) for name in names: - if timeline_data.is_author_in_periods(periods, name): + if timeline_data.is_author_in_periods(periods, name[0]): print(name[0].ljust(20)[0:20], end=" ") for period in periods: multiplier = timeline_data.get_multiplier(period, 9) - signs = timeline_data.get_author_signs_in_period(name, period, multiplier) + signs = timeline_data.get_author_signs_in_period(name[0], period, multiplier) signs_str = (signs[1] * "-" + signs[0] * "+") - print (("." if timeline_data.is_author_in_period(period, name) and + print (("." if timeline_data.is_author_in_period(period, name[0]) and len(signs_str) == 0 else signs_str).rjust(10), end=" ") print("") @@ -146,9 +146,8 @@ def __output_row__html__(timeline_data, periods, names): i = 0 for name in names: - if timeline_data.is_author_in_periods(periods, name): + if timeline_data.is_author_in_periods(periods, name[0]): timeline_xml += "" if i % 2 == 1 else ">") - #timeline_xml += "" + name[0] + "" if format.get_selected() == "html": timeline_xml += "{1}".format(gravatar.get_url(name[1]), name[0]) @@ -156,11 +155,11 @@ def __output_row__html__(timeline_data, periods, names): timeline_xml += "" + name[0] + "" for period in periods: - multiplier = timeline_data.get_multiplier(period, 14) - signs = timeline_data.get_author_signs_in_period(name, period, multiplier) + multiplier = timeline_data.get_multiplier(period, 18) + signs = timeline_data.get_author_signs_in_period(name[0], period, multiplier) signs_str = (signs[1] * "
 
" + signs[0] * "
 
") - timeline_xml += "" + ("." if timeline_data.is_author_in_period(period, name) and len(signs_str) == 0 else signs_str) + timeline_xml += "" + ("." if timeline_data.is_author_in_period(period, name[0]) and len(signs_str) == 0 else signs_str) timeline_xml += "" timeline_xml += "" i = i + 1 @@ -225,9 +224,9 @@ class Timeline(Outputable): authors_xml = "\t\t\t\t\n" for name in names: - if timeline_data.is_author_in_period(period, name): + if timeline_data.is_author_in_period(period, name[0]): multiplier = timeline_data.get_multiplier(period, 24) - signs = timeline_data.get_author_signs_in_period(name, period, multiplier) + signs = timeline_data.get_author_signs_in_period(name[0], period, multiplier) signs_str = (signs[1] * "-" + signs[0] * "+") if len(signs_str) == 0: