Skip to content

Commit ea583e1

Browse files
authored
Merge pull request #1943 from JonasScharpf/feature/add-change-type-to-commit-stats
Add type of change to files_dict of a commit
2 parents 89822f8 + ce8a69a commit ea583e1

File tree

7 files changed

+40
-16
lines changed

7 files changed

+40
-16
lines changed

Diff for: AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,6 @@ Contributors are:
5454
-Wenhan Zhu <wzhu.cosmos _at_ gmail.com>
5555
-Eliah Kagan <eliah.kagan _at_ gmail.com>
5656
-Ethan Lin <et.repositories _at_ gmail.com>
57+
-Jonas Scharpf <jonas.scharpf _at_ checkmk.com>
5758

5859
Portions derived from other open source works and are clearly marked.

Diff for: git/objects/commit.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -377,15 +377,25 @@ def stats(self) -> Stats:
377377
:return:
378378
:class:`Stats`
379379
"""
380-
if not self.parents:
381-
text = self.repo.git.diff_tree(self.hexsha, "--", numstat=True, no_renames=True, root=True)
382-
text2 = ""
383-
for line in text.splitlines()[1:]:
380+
381+
def process_lines(lines: List[str]) -> str:
382+
text = ""
383+
for file_info, line in zip(lines, lines[len(lines) // 2 :]):
384+
change_type = file_info.split("\t")[0][-1]
384385
(insertions, deletions, filename) = line.split("\t")
385-
text2 += "%s\t%s\t%s\n" % (insertions, deletions, filename)
386-
text = text2
386+
text += "%s\t%s\t%s\t%s\n" % (change_type, insertions, deletions, filename)
387+
return text
388+
389+
if not self.parents:
390+
lines = self.repo.git.diff_tree(
391+
self.hexsha, "--", numstat=True, no_renames=True, root=True, raw=True
392+
).splitlines()[1:]
393+
text = process_lines(lines)
387394
else:
388-
text = self.repo.git.diff(self.parents[0].hexsha, self.hexsha, "--", numstat=True, no_renames=True)
395+
lines = self.repo.git.diff(
396+
self.parents[0].hexsha, self.hexsha, "--", numstat=True, no_renames=True, raw=True
397+
).splitlines()
398+
text = process_lines(lines)
389399
return Stats._list_from_string(self.repo, text)
390400

391401
@property

Diff for: git/types.py

+1
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ class Files_TD(TypedDict):
248248
insertions: int
249249
deletions: int
250250
lines: int
251+
change_type: str
251252

252253

253254
class Total_TD(TypedDict):

Diff for: git/util.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,7 @@ class Stats:
910910
deletions = number of deleted lines as int
911911
insertions = number of inserted lines as int
912912
lines = total number of lines changed as int, or deletions + insertions
913+
change_type = type of change as str, A|C|D|M|R|T|U|X|B
913914
914915
``full-stat-dict``
915916
@@ -938,7 +939,7 @@ def _list_from_string(cls, repo: "Repo", text: str) -> "Stats":
938939
"files": {},
939940
}
940941
for line in text.splitlines():
941-
(raw_insertions, raw_deletions, filename) = line.split("\t")
942+
(change_type, raw_insertions, raw_deletions, filename) = line.split("\t")
942943
insertions = raw_insertions != "-" and int(raw_insertions) or 0
943944
deletions = raw_deletions != "-" and int(raw_deletions) or 0
944945
hsh["total"]["insertions"] += insertions
@@ -949,6 +950,7 @@ def _list_from_string(cls, repo: "Repo", text: str) -> "Stats":
949950
"insertions": insertions,
950951
"deletions": deletions,
951952
"lines": insertions + deletions,
953+
"change_type": change_type,
952954
}
953955
hsh["files"][filename.strip()] = files_dict
954956
return Stats(hsh["total"], hsh["files"])

Diff for: test/fixtures/diff_numstat

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
29 18 a.txt
2-
0 5 b.txt
1+
M 29 18 a.txt
2+
M 0 5 b.txt
3+
A 7 0 c.txt

Diff for: test/test_commit.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,12 @@ def test_stats(self):
135135
commit = self.rorepo.commit("33ebe7acec14b25c5f84f35a664803fcab2f7781")
136136
stats = commit.stats
137137

138-
def check_entries(d):
138+
def check_entries(d, has_change_type=False):
139139
assert isinstance(d, dict)
140-
for key in ("insertions", "deletions", "lines"):
140+
keys = ("insertions", "deletions", "lines")
141+
if has_change_type:
142+
keys += ("change_type",)
143+
for key in keys:
141144
assert key in d
142145

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

150153
for _filepath, d in stats.files.items():
151-
check_entries(d)
154+
check_entries(d, True)
152155
# END for each stated file
153156

154157
# Check that data is parsed properly.

Diff for: test/test_stats.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@ def test_list_from_string(self):
1414
output = fixture("diff_numstat").decode(defenc)
1515
stats = Stats._list_from_string(self.rorepo, output)
1616

17-
self.assertEqual(2, stats.total["files"])
18-
self.assertEqual(52, stats.total["lines"])
19-
self.assertEqual(29, stats.total["insertions"])
17+
self.assertEqual(3, stats.total["files"])
18+
self.assertEqual(59, stats.total["lines"])
19+
self.assertEqual(36, stats.total["insertions"])
2020
self.assertEqual(23, stats.total["deletions"])
2121

2222
self.assertEqual(29, stats.files["a.txt"]["insertions"])
2323
self.assertEqual(18, stats.files["a.txt"]["deletions"])
24+
self.assertEqual("M", stats.files["a.txt"]["change_type"])
2425

2526
self.assertEqual(0, stats.files["b.txt"]["insertions"])
2627
self.assertEqual(5, stats.files["b.txt"]["deletions"])
28+
self.assertEqual("M", stats.files["b.txt"]["change_type"])
29+
30+
self.assertEqual(7, stats.files["c.txt"]["insertions"])
31+
self.assertEqual(0, stats.files["c.txt"]["deletions"])
32+
self.assertEqual("A", stats.files["c.txt"]["change_type"])

0 commit comments

Comments
 (0)