Skip to content

Commit e296473

Browse files
authored
Merge pull request #2280 from v1shay/fix/stats-filename-spaces
fix(stats): preserve whitespace in filenames
2 parents 804bc80 + 963ca1c commit e296473

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

‎git/util.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,7 @@ def _list_from_string(cls, repo: "Repo", text: str) -> "Stats":
11071107
"lines": insertions + deletions,
11081108
"change_type": change_type,
11091109
}
1110-
hsh["files"][filename.strip()] = files_dict
1110+
hsh["files"][filename] = files_dict
11111111
return Stats(hsh["total"], hsh["files"])
11121112

11131113

‎test/test_commit.py‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
from git import Actor, Commit, Repo
1919
from git.exc import UnsafeOptionError
20+
from git.index.typ import BaseIndexEntry
2021
from git.objects.util import tzoffset, utc
2122
from git.repo.fun import touch
2223

@@ -166,6 +167,39 @@ def check_entries(d, has_change_type=False):
166167
self.assertEqual(commit.committer_tz_offset, 14400, commit.committer_tz_offset)
167168
self.assertEqual(commit.message, "initial project\n")
168169

170+
@with_rw_directory
171+
def test_stats_preserve_filename_spaces(self, rw_dir):
172+
repo = Repo.init(rw_dir)
173+
actor = Actor("Test", "test@example.com")
174+
paths = ("name", " name", "name ", " name ", " ")
175+
# Store blobs directly so trailing spaces work on Windows as well.
176+
for multiplier, change_type in ((1, "A"), (2, "M")):
177+
for count, path in enumerate(paths, 1):
178+
data = b"line\n" * count * multiplier
179+
blob = repo.odb.store(IStream("blob", len(data), BytesIO(data)))
180+
repo.index.add([BaseIndexEntry((0o100644, blob.binsha, 0, path))])
181+
commit = repo.index.commit("Update files", author=actor, committer=actor)
182+
stats = commit.stats
183+
assert stats.total == {"insertions": 15, "deletions": 0, "lines": 15, "files": 5}
184+
assert stats.files == {
185+
path: {"insertions": count, "deletions": 0, "lines": count, "change_type": change_type}
186+
for count, path in enumerate(paths, 1)
187+
}
188+
empty_stats = repo.index.commit("No changes", author=actor, committer=actor).stats
189+
assert empty_stats.files == {}
190+
assert empty_stats.total == {"insertions": 0, "deletions": 0, "lines": 0, "files": 0}
191+
192+
# Avoid filesystem path normalization of space-only names on Windows.
193+
index = repo.index
194+
index.entries.clear()
195+
index.write()
196+
removed_stats = repo.index.commit("Remove files", author=actor, committer=actor).stats
197+
assert removed_stats.files == {
198+
path: {"insertions": 0, "deletions": 2 * count, "lines": 2 * count, "change_type": "D"}
199+
for count, path in enumerate(paths, 1)
200+
}
201+
assert removed_stats.total == {"insertions": 0, "deletions": 30, "lines": 30, "files": 5}
202+
169203
def test_renames(self):
170204
commit = self.rorepo.commit("185d847ec7647fd2642a82d9205fb3d07ea71715")
171205
files = commit.stats.files

0 commit comments

Comments
 (0)