Skip to content

Commit c186cae

Browse files
committed
test: cover Cygwin index filename restrictions
The partial Cygwin fast-suite log exposed a failure in `test_valid_unusual_index_names_round_trip`: native Git omitted a literal backslash filename. Cygwin Git recognizes Windows separators and applies NTFS path protection, even though Python reports a POSIX platform. Move that case into the existing unsupported-name assertions for Cygwin. Check that GitPython raises `ValueError`, preserves the published index, and removes its lock. Other POSIX systems retain the round-trip case; Windows retains the control-character and colon rejection cases. Document the Cygwin restriction in `changes.rst`. Validation: three focused index tests pass locally. The Cygwin and Windows test branches pass with only Git's ignored-record behavior simulated; native Cygwin verification awaits CI. Ruff lint, formatting, and `git diff --check` pass.
1 parent b99404a commit c186cae

2 files changed

Lines changed: 19 additions & 13 deletions

File tree

‎doc/source/changes.rst‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ API changes
6565
indexes isolate tree/merge operations from the real index and working tree.
6666
Git's platform-specific index filename restrictions apply. Unsupported entries
6767
raise ``ValueError`` before the original index changes, including names with
68-
colons or control characters on Windows. Tree objects can still contain names
69-
that the working tree or index cannot represent.
68+
colons or control characters on Windows and backslashes with Cygwin Git.
69+
Tree objects can still contain names that the working tree or index cannot
70+
represent.
7071
``version`` is read-only. ``from_tree()`` accepts ``trivial``, ``aggressive``,
7172
and ``verbose`` options; arbitrary ``read-tree`` keyword forwarding is removed.
7273
* Standalone binary tree parsers, serializers, and multi-tree traversal helpers

‎test/test_index.py‎

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,23 +212,28 @@ def test_index_reader_and_writer_reject_unsafe_paths(self, path):
212212

213213
def test_valid_unusual_index_names_round_trip(self):
214214
names = ["a b", "--option", "dir/.gitignore", "café"]
215-
windows_unsupported = ["a\nb", "a\tb", "name:value"]
215+
unsupported = ["a\nb", "a\tb", "name:value"]
216216
if os.name != "nt":
217-
names.extend([*windows_unsupported, "a\\b", "\udc9f"])
217+
names.extend([*unsupported, "\udc9f"])
218+
unsupported = []
219+
if sys.platform == "cygwin":
220+
# Cygwin Git applies NTFS protection to backslash separators.
221+
unsupported.append("a\\b")
222+
else:
223+
names.append("a\\b")
218224
with tempfile.TemporaryDirectory() as directory:
219225
index = IndexFile(self.rorepo, Path(directory, "index"))
220226
index.entries = {(name, 0): IndexEntry((0o100644, b"a" * 20, 0, name)) for name in names}
221227
index.write()
222228
assert sorted(entry.path for entry in index.update().entries.values()) == sorted(names)
223-
if os.name == "nt":
224-
before = Path(index.path).read_bytes()
225-
for name in windows_unsupported:
226-
index.entries[(name, 0)] = IndexEntry((0o100644, b"a" * 20, 0, name))
227-
with pytest.raises(ValueError, match="Git did not retain"):
228-
index.write()
229-
assert Path(index.path).read_bytes() == before
230-
assert not Path(str(index.path) + ".lock").exists()
231-
del index.entries[(name, 0)]
229+
before = Path(index.path).read_bytes()
230+
for name in unsupported:
231+
index.entries[(name, 0)] = IndexEntry((0o100644, b"a" * 20, 0, name))
232+
with pytest.raises(ValueError, match="Git did not retain"):
233+
index.write()
234+
assert Path(index.path).read_bytes() == before
235+
assert not Path(str(index.path) + ".lock").exists()
236+
del index.entries[(name, 0)]
232237

233238
@ddt.data("write", "write_tree")
234239
def test_index_rejects_silently_ignored_entries_atomically(self, operation):

0 commit comments

Comments
 (0)