Python脚本未能在Windows中删除Git文件

7

我正在使用以下代码来删除包含 git 存储库的目录:

import errno
import os
import stat
import shutil


def clear_dir(path):
    shutil.rmtree(path, ignore_errors=False, onerror=handle_remove_readonly)


def handle_remove_readonly(func, path, exc):
  excvalue = exc[1]
  if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
      os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO) # 0777
      func(path)
  else:
      raise

这段代码应该能够很好地处理只读文件。我可以从Windows资源管理器中删除目录/文件夹,但是当我运行以下代码时:

if __name__ == '__main__':
    clear_dir(r'c:\path\to\ci-monitor')

我遇到了以下错误:

  File "C:\Users\m45914\code\ci-monitor\utils\filehandling.py", line 8, in clear_dir                              
    shutil.rmtree(path, ignore_errors=False, onerror=handle_remove_readonly)                                      
  File "C:\Users\m45914\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 488, in rmtree                
    return _rmtree_unsafe(path, onerror)                                                                          
  File "C:\Users\m45914\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 378, in _rmtree_unsafe        
    _rmtree_unsafe(fullname, onerror)                                                                             
  File "C:\Users\m45914\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 378, in _rmtree_unsafe        
    _rmtree_unsafe(fullname, onerror)                                                                             
  File "C:\Users\m45914\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 378, in _rmtree_unsafe        
    _rmtree_unsafe(fullname, onerror)                                                                             
  File "C:\Users\m45914\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 378, in _rmtree_unsafe        
    _rmtree_unsafe(fullname, onerror)                                                                             
  File "C:\Users\m45914\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 383, in _rmtree_unsafe        
    onerror(os.unlink, fullname, sys.exc_info())                                                                  
  File "C:\Users\m45914\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 381, in _rmtree_unsafe        
    os.unlink(fullname)                                                                                           
PermissionError: [WinError 5] Access is denied: 'scratch\\repos\\ci-monitor\\.git\\objects\\pack\\pack-83e55c6964d
21e8be0afb2cbccd887eae3e32bf4.idx'                                                                                

我尝试以管理员身份运行脚本(没有变化)。

要删除的目录是一个git仓库,我定期克隆、检查和删除它。检查是为了确保仓库中没有未合并的发布和热修复分支。

有人有任何想法吗?


为什么你认为“拒绝访问”是由文件只读引起的?有很多原因会导致访问冲突,其中之一就是文件属于另一个用户。在Windows上,权限设置与其他系统显著不同,简单的chmod命令通常是不够的。Chmod的文档说:“虽然Windows支持chmod(),但你只能使用它来设置文件的只读标志(通过stat.S_IWRITE和stat.S_IREAD常量或相应的整数值)。所有其他位都将被忽略。”请尝试使用ICacls代替。 - Basic
不确定,但看起来你对函数名称检查过于严格了。 - jthill
可能是shutil.rmtree在Windows上失败,显示“访问被拒绝”的重复问题。 - Ocaso Protal
这个回答解决了你的问题吗?如何在Windows上使用Python删除Git存储库 - tejasvi88
2个回答

2

如果该文件正在被其他进程使用,则无法删除它。通过使用“unlocker”或任何类似的软件进行交叉检查。


2
谢谢您的回答,但如果是这种情况,我就无法在Windows资源管理器中删除它。 - Nic
1
你尝试过这里提到的解决方案吗?它说rmtree在删除只读文件时会出现问题。它还提供了一个解决方案。 https://dev59.com/-HM_5IYBdhLWcg3w02v8 - saurabh baid
谢谢Saurabh,我的代码是从你提到的帖子中改编的。 - Nic
1
如果这是一个共享问题,ERROR_ACCESS_DENIED(5)意味着某个进程已经将文件映射到内存中(可执行文件或数据),您至少可以将该文件重命名为同一卷上的另一个目录。大多数共享问题实际上是由于基本访问共享(例如FILE_SHARE_DELETE)而引起的,并显示为ERROR_SHARING_VIOLATION(32),但这里并非如此。 - Eryk Sun
2
另一个可能性是文件使用FILE_SHARE_DELETE打开,然后在关闭句柄之前被删除。在所有引用关闭之前,Windows不会从目录中取消链接文件。如果文件当前处于“已删除”状态(这只是文件控制块上的标志),则无法为任何访问打开新句柄。删除文件需要使用具有DELETE访问权限的句柄,因此DeleteFile将失败并显示ERROR_ACCESS_DENIED。在文件取消链接之前,父目录也无法被删除。 - Eryk Sun

2

我遇到了同样的问题。我通过将os.unlink添加到函数列表中来解决它:

if func in (os.rmdir, os.remove, os.unlink) and excvalue.errno == errno.EACCES:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接