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).
This commit is contained in:
Adam Waldenberg 2013-07-22 05:51:56 +02:00
parent 35852f9859
commit 662cd3fa63
3 changed files with 36 additions and 36 deletions

View File

@ -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 += "<tr " + ("class=\"odd\">" if i % 2 == 1 else ">")
if format.get_selected() == "html":
blame_xml += "<td><img src=\"{0}\"/>{1}</td>".format(gravatar.get_url(entry[0]), authorname)
blame_xml += "<td><img src=\"{0}\"/>{1}</td>".format(gravatar.get_url(author_email), entry[0])
else:
blame_xml += "<td>" + authorname + "</td>"
@ -186,7 +186,7 @@ class BlameOutput(Outputable):
blame_xml += "<td>" + "{0:.2f}".format(100.0 * entry[1].comments / entry[1].rows) + "</td>"
blame_xml += "<td style=\"display: none\">" + work_percentage + "</td>"
blame_xml += "</tr>"
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<name>" + authorname + "</name>\n"
gravatar_xml = "\t\t\t\t<gravatar>" + gravatar.get_url(i[0]) + "</gravatar>\n"
author_email = self.changes.get_author_email(i[0])
name_xml = "\t\t\t\t<name>" + i[0] + "</name>\n"
gravatar_xml = "\t\t\t\t<gravatar>" + gravatar.get_url(author_email) + "</gravatar>\n"
rows_xml = "\t\t\t\t<rows>" + str(i[1].rows) + "</rows>\n"
percentage_in_comments_xml = ("\t\t\t\t<percentage-in-comments>" + "{0:.2f}".format(100.0 * i[1].comments / i[1].rows) +
"</percentage-in-comments>\n")

View File

@ -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 += "<tr " + ("class=\"odd\">" if i % 2 == 1 else ">")
if format.get_selected() == "html":
changes_xml += "<td><img src=\"{0}\"/>{1}</td>".format(gravatar.get_url(entry[1]), entry[0])
changes_xml += "<td><img src=\"{0}\"/>{1}</td>".format(gravatar.get_url(authorinfo.email), entry)
else:
changes_xml += "<td>" + entry[0] + "</td>"
@ -214,7 +214,7 @@ class ChangesOutput(Outputable):
changes_xml += "<td>" + str(authorinfo.deletions) + "</td>"
changes_xml += "<td>" + "{0:.2f}".format(percentage) + "</td>"
changes_xml += "</tr>"
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<name>" + i[0] + "</name>\n"
gravatar_xml = "\t\t\t\t<gravatar>" + gravatar.get_url(i[1]) + "</gravatar>\n"
name_xml = "\t\t\t\t<name>" + i + "</name>\n"
gravatar_xml = "\t\t\t\t<gravatar>" + gravatar.get_url(authorinfo.email) + "</gravatar>\n"
commits_xml = "\t\t\t\t<commits>" + str(authorinfo.commits) + "</commits>\n"
insertions_xml = "\t\t\t\t<insertions>" + str(authorinfo.insertions) + "</insertions>\n"
deletions_xml = "\t\t\t\t<deletions>" + str(authorinfo.deletions) + "</deletions>\n"

View File

@ -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 += "<tr" + (" class=\"odd\">" if i % 2 == 1 else ">")
#timeline_xml += "<td>" + name[0] + "</td>"
if format.get_selected() == "html":
timeline_xml += "<td><img src=\"{0}\"/>{1}</td>".format(gravatar.get_url(name[1]), name[0])
@ -156,11 +155,11 @@ def __output_row__html__(timeline_data, periods, names):
timeline_xml += "<td>" + name[0] + "</td>"
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] * "<div class=\"remove\">&nbsp;</div>" + signs[0] * "<div class=\"insert\">&nbsp;</div>")
timeline_xml += "<td>" + ("." if timeline_data.is_author_in_period(period, name) and len(signs_str) == 0 else signs_str)
timeline_xml += "<td>" + ("." if timeline_data.is_author_in_period(period, name[0]) and len(signs_str) == 0 else signs_str)
timeline_xml += "</td>"
timeline_xml += "</tr>"
i = i + 1
@ -225,9 +224,9 @@ class Timeline(Outputable):
authors_xml = "\t\t\t\t<authors>\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: