Skip to content

Commit f09a85a

Browse files
authored
Merge pull request #442 from mdboom/windows-git-rmtree
Use a special technique to remove git repos on Windows
2 parents 8c89198 + 46e3954 commit f09a85a

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## Unreleased
22

3+
### Bugfixes
4+
5+
#### Removing a git repo on Windows fails
6+
7+
One needs to remove the "read only" flags on certain files in the git repo in order to remove it.
8+
39
## 2.0.0
410

511
### Moving more code to Python

bench_runner/git.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import contextlib
66
import datetime
77
from pathlib import Path
8-
import shutil
98
import subprocess
109
import re
1110

@@ -14,6 +13,7 @@
1413

1514

1615
from .util import PathLike
16+
from . import util
1717

1818

1919
def get_log(
@@ -147,7 +147,7 @@ def clone(
147147
if is_hash and (dirname / ".git").is_dir() and get_git_hash(dirname) == branch:
148148
# This is a git repo, and the hash matches
149149
return
150-
shutil.rmtree(dirname)
150+
util.smart_rmtree(dirname)
151151

152152
# Fetching a hash and fetching a branch require different approaches
153153

bench_runner/util.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from pathlib import Path
66
import shutil
77
import subprocess
8+
import stat
89
import sys
910
from typing import Iterable, Iterator, Literal, TypeAlias, Union
1011

@@ -105,6 +106,37 @@ def valid_version(version: str) -> bool:
105106
return False
106107

107108

109+
if sys.platform.startswith("win"):
110+
if sys.version_info >= (3, 12):
111+
112+
def smart_rmtree(path: PathLike) -> None:
113+
def onexc(func, path, exc):
114+
# Is the error an access error?
115+
if not os.access(path, os.W_OK):
116+
os.chmod(path, stat.S_IWUSR)
117+
func(path)
118+
else:
119+
raise exc
120+
121+
shutil.rmtree(path, onexc=onexc)
122+
123+
else:
124+
125+
def smart_rmtree(path: PathLike) -> None:
126+
def onerror(func, path, exc_info):
127+
# Is the error an access error?
128+
if not os.access(path, os.W_OK):
129+
os.chmod(path, stat.S_IWUSR)
130+
func(path)
131+
else:
132+
raise exc_info[1]
133+
134+
shutil.rmtree(path, onerror=onerror)
135+
136+
else:
137+
smart_rmtree = shutil.rmtree
138+
139+
108140
if os.getenv("GITHUB_ACTIONS") == "true":
109141

110142
@contextlib.contextmanager

0 commit comments

Comments
 (0)