Skip to content

Commit 50d88aa

Browse files
authored
Merge pull request #2328 from EliahKagan/claude/rmfile-chmod-owner-write
refactor(util): clear read-only in `rmfile` with `stat.S_IWUSR`
2 parents 38992bc + 53f3c62 commit 50d88aa

3 files changed

Lines changed: 21 additions & 1 deletion

File tree

‎git/util.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def rmfile(path: PathLike) -> None:
211211
treatment."""
212212
if osp.isfile(path):
213213
if sys.platform == "win32":
214-
os.chmod(path, 0o777)
214+
os.chmod(path, stat.S_IWUSR)
215215
os.remove(path)
216216

217217

‎test/test_util.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
is_cygwin_git,
4242
join_path,
4343
remove_password_if_present,
44+
rmfile,
4445
rmtree,
4546
stream_copy,
4647
)
@@ -213,6 +214,21 @@ def preen_dir2():
213214
assert old_mode == new_mode, f"Should stay {old_mode:#o}, became {new_mode:#o}."
214215

215216

217+
class TestRmfile:
218+
"""Tests for :func:`git.util.rmfile`."""
219+
220+
def test_deletes_readonly_file(self):
221+
# Automatically works on Unix, but requires special handling on Windows.
222+
with writable_fixture("rmfile.sh") as temporary:
223+
file = temporary.path().resolve() / "readonly"
224+
# rmfile ignores missing paths, so check that the fixture made a read-only file.
225+
assert file.is_file()
226+
assert not file.stat().st_mode & stat.S_IWUSR
227+
228+
rmfile(file)
229+
assert not file.exists()
230+
231+
216232
def _xfail_param(*values, **xfail_kwargs):
217233
"""Build a pytest.mark.parametrize parameter that carries an xfail mark."""
218234
return pytest.param(*values, marks=pytest.mark.xfail(**xfail_kwargs))

‎tests/fixtures/rmfile.sh‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
set -eu
3+
touch readonly
4+
chmod a-w readonly

0 commit comments

Comments
 (0)