diff options
-rw-r--r-- | git/objects/submodule/base.py | 7 | ||||
-rw-r--r-- | git/util.py | 17 |
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 |