summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--git/objects/submodule/base.py7
-rw-r--r--git/util.py17
2 files changed, 19 insertions, 5 deletions
diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
index a33dd8ad..1b94f522 100644
--- a/git/objects/submodule/base.py
+++ b/git/objects/submodule/base.py
@@ -18,6 +18,7 @@ from git.util import (
Iterable,
join_path_native,
to_native_path_linux,
+ rmtree
)
from git.db.interface import RemoteProgress
@@ -35,8 +36,6 @@ import os
import sys
import time
-import shutil
-
__all__ = ["Submodule", "UpdateProgress"]
@@ -634,7 +633,7 @@ class Submodule(util.IndexObject, Iterable, Traversable, RepoAliasMixin):
if os.path.islink(mp):
method = os.remove
elif os.path.isdir(mp):
- method = shutil.rmtree
+ method = rmtree
elif os.path.exists(mp):
raise AssertionError("Cannot forcibly delete repository as it was neither a link, nor a directory")
#END handle brutal deletion
@@ -683,7 +682,7 @@ class Submodule(util.IndexObject, Iterable, Traversable, RepoAliasMixin):
if not dry_run:
wtd = mod.working_tree_dir
del(mod) # release file-handles (windows)
- shutil.rmtree(wtd)
+ rmtree(wtd)
# END delete tree if possible
# END handle force
# END handle module deletion
diff --git a/git/util.py b/git/util.py
index 01940763..a31e5865 100644
--- a/git/util.py
+++ b/git/util.py
@@ -12,12 +12,14 @@ import sys
import errno
import re
import time
+import stat
+import shutil
import tempfile
__all__ = ( "stream_copy", "join_path", "to_native_path_windows", "to_native_path_linux",
"join_path_native", "Stats", "IndexFileSHA1Writer", "Iterable", "IterableList",
"BlockingLockFile", "LockFile", 'Actor', 'get_user_id', 'assure_directory_exists',
- 'RepoAliasMixin', 'LockedFD', 'LazyMixin' )
+ 'RepoAliasMixin', 'LockedFD', 'LazyMixin', 'rmtree' )
from cStringIO import StringIO
@@ -147,6 +149,19 @@ def is_git_dir(d):
os.readlink(headref).startswith('refs'))
return False
+def rmtree(path):
+ """Remove the given recursively.
+ :note: we use shutil rmtree but adjust its behaviour to see whether files that
+ couldn't be deleted are read-only. Windows will not remove them in that case"""
+ def onerror(func, path, exc_info):
+ if not os.access(path, os.W_OK):
+ # Is the error an access error ?
+ os.chmod(path, stat.S_IWUSR)
+ func(path)
+ else:
+ raise
+ # END end onerror
+ return shutil.rmtree(path, False, onerror)
def stream_copy(source, destination, chunk_size=512*1024):
"""Copy all data from the source stream into the destination stream in chunks