Skip to content

Commit

Permalink
Merge pull request gitpython-developers#1943 from JonasScharpf/featur…
Browse files Browse the repository at this point in the history
…e/add-change-type-to-commit-stats

Add type of change to files_dict of a commit
  • Loading branch information
Byron authored Jul 18, 2024
2 parents 89822f8 + ce8a69a commit ea583e1
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 16 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ Contributors are:
-Wenhan Zhu <wzhu.cosmos _at_ gmail.com>
-Eliah Kagan <eliah.kagan _at_ gmail.com>
-Ethan Lin <et.repositories _at_ gmail.com>
-Jonas Scharpf <jonas.scharpf _at_ checkmk.com>

Portions derived from other open source works and are clearly marked.
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:]:

def process_lines(lines: List[str]) -> str:
text = ""
for file_info, line in zip(lines, lines[len(lines) // 2 :]):
change_type = file_info.split("\t")[0][-1]
(insertions, deletions, filename) = line.split("\t")
text2 += "%s\t%s\t%s\n" % (insertions, deletions, filename)
text = text2
text += "%s\t%s\t%s\t%s\n" % (change_type, insertions, deletions, filename)
return text

if not self.parents:
lines = self.repo.git.diff_tree(
self.hexsha, "--", numstat=True, no_renames=True, root=True, raw=True
).splitlines()[1:]
text = process_lines(lines)
else:
text = self.repo.git.diff(self.parents[0].hexsha, self.hexsha, "--", numstat=True, no_renames=True)
lines = self.repo.git.diff(
self.parents[0].hexsha, self.hexsha, "--", numstat=True, no_renames=True, raw=True
).splitlines()
text = process_lines(lines)
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
change_type: str


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
change_type = type of change as str, A|C|D|M|R|T|U|X|B
``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")
(change_type, 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
Expand All @@ -949,6 +950,7 @@ def _list_from_string(cls, repo: "Repo", text: str) -> "Stats":
"insertions": insertions,
"deletions": deletions,
"lines": insertions + deletions,
"change_type": change_type,
}
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
M 29 18 a.txt
M 0 5 b.txt
A 7 0 c.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):
def check_entries(d, has_change_type=False):
assert isinstance(d, dict)
for key in ("insertions", "deletions", "lines"):
keys = ("insertions", "deletions", "lines")
if has_change_type:
keys += ("change_type",)
for key in keys:
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)
check_entries(d, True)
# 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(3, stats.total["files"])
self.assertEqual(59, stats.total["lines"])
self.assertEqual(36, 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("M", stats.files["a.txt"]["change_type"])

self.assertEqual(0, stats.files["b.txt"]["insertions"])
self.assertEqual(5, stats.files["b.txt"]["deletions"])
self.assertEqual("M", stats.files["b.txt"]["change_type"])

self.assertEqual(7, stats.files["c.txt"]["insertions"])
self.assertEqual(0, stats.files["c.txt"]["deletions"])
self.assertEqual("A", stats.files["c.txt"]["change_type"])

0 comments on commit ea583e1

Please sign in to comment.