◐ Shell
reader mode source ↗
Skip to content
Merged
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
24 changes: 17 additions & 7 deletions git/objects/commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,15 +377,25 @@ def stats(self) -> Stats:
:return:
:class:`Stats`
"""
if not self.parents:
text = self.repo.git.diff_tree(self.hexsha, "--", numstat=True, no_renames=True, root=True)
text2 = ""
for line in text.splitlines()[1:]:
(insertions, deletions, filename) = line.split("\t")
text2 += "%s\t%s\t%s\n" % (insertions, deletions, filename)
text = text2
else:
text = self.repo.git.diff(self.parents[0].hexsha, self.hexsha, "--", numstat=True, no_renames=True)
return Stats._list_from_string(self.repo, text)

@property
Expand Down
1 change: 1 addition & 0 deletions git/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ class Files_TD(TypedDict):
insertions: int
deletions: int
lines: int


class Total_TD(TypedDict):
Expand Down
4 changes: 3 additions & 1 deletion git/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ class Stats:
deletions = number of deleted lines as int
insertions = number of inserted lines as int
lines = total number of lines changed as int, or deletions + insertions

``full-stat-dict``

Expand Down Expand Up @@ -938,7 +939,7 @@ def _list_from_string(cls, repo: "Repo", text: str) -> "Stats":
"files": {},
}
for line in text.splitlines():
(raw_insertions, raw_deletions, filename) = line.split("\t")
insertions = raw_insertions != "-" and int(raw_insertions) or 0
deletions = raw_deletions != "-" and int(raw_deletions) or 0
hsh["total"]["insertions"] += insertions
@@ -949,6 +950,7 @@ def _list_from_string(cls, repo: "Repo", text: str) -> "Stats":
"insertions": insertions,
"deletions": deletions,
"lines": insertions + deletions,
}
hsh["files"][filename.strip()] = files_dict
return Stats(hsh["total"], hsh["files"])
Expand Down
5 changes: 3 additions & 2 deletions test/fixtures/diff_numstat
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
29 18 a.txt
0 5 b.txt
9 changes: 6 additions & 3 deletions test/test_commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,12 @@ def test_stats(self):
commit = self.rorepo.commit("33ebe7acec14b25c5f84f35a664803fcab2f7781")
stats = commit.stats

def check_entries(d):
assert isinstance(d, dict)
for key in ("insertions", "deletions", "lines"):
assert key in d

# END assertion helper
Expand All @@ -148,7 +151,7 @@ def check_entries(d):
assert "files" in stats.total

for _filepath, d in stats.files.items():
check_entries(d)
# END for each stated file

# Check that data is parsed properly.
Expand Down
12 changes: 9 additions & 3 deletions test/test_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@ def test_list_from_string(self):
output = fixture("diff_numstat").decode(defenc)
stats = Stats._list_from_string(self.rorepo, output)

self.assertEqual(2, stats.total["files"])
self.assertEqual(52, stats.total["lines"])
self.assertEqual(29, stats.total["insertions"])
self.assertEqual(23, stats.total["deletions"])

self.assertEqual(29, stats.files["a.txt"]["insertions"])
self.assertEqual(18, stats.files["a.txt"]["deletions"])

self.assertEqual(0, stats.files["b.txt"]["insertions"])
self.assertEqual(5, stats.files["b.txt"]["deletions"])
Toggle all file notes Toggle all file annotations