为什么 Git for Windows 创建我无法从命令行删除的存储库?

Chr*_*ong 15 git windows-10

我刚刚“重置”了 Windows 10 的安装。我从https://git-scm.org/安装了 Git 的“Git for Windows”发行版。

如果我以任何方式(无论是init还是clone)创建一个 git 存储库,则无法使用命令行提示符从我的文件系统中删除该存储库。我必须使用 Windows 资源管理器来做到这一点。

这是一个示例会话:

PS C:\Users\radix> mkdir foo


    Directory: C:\Users\radix


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        5/10/2018   5:46 PM                foo


PS C:\Users\radix> cd foo
PS C:\Users\radix\foo> git init .
Initialized empty Git repository in C:/Users/radix/foo/.git/
PS C:\Users\radix\foo> cd ..
PS C:\Users\radix> rm foo -Recurse
rm : Cannot remove item C:\Users\radix\foo\.git: You do not have sufficient access rights to perform this operation.
At line:1 char:1
+ rm foo -Recurse
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (.git:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemUnAuthorizedAccess,Microsoft.PowerShell.Commands.RemoveItemCommand
rm : Directory C:\Users\radix\foo cannot be removed because it is not empty.
At line:1 char:1
+ rm foo -Recurse
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\Users\radix\foo:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : DirectoryNotEmpty,Microsoft.PowerShell.Commands.RemoveItemCommand
Run Code Online (Sandbox Code Playgroud)

这是以我的普通用户身份运行的 PowerShell。即使我以管理员身份运行 Powershell,该rm -Recurse命令仍然以完全相同的方式失败。我知道删除这个新foo目录的唯一方法是通过 Windows 资源管理器来完成,它甚至不会抱怨或提示权限 - 它只是默默地删除它,没有问题。

我不认为这是 PowerShell 特定的问题,因为在 CMD 中发生了类似的行为:

C:\Users\radix>dir foo
 Volume in drive C is Blade
 Volume Serial Number is B83C-EF1B

 Directory of C:\Users\radix

File Not Found

C:\Users\radix>git init foo
Initialized empty Git repository in C:/Users/radix/foo/.git/

C:\Users\radix>del foo
C:\Users\radix\foo\*, Are you sure (Y/N)? y

C:\Users\radix>dir foo
 Volume in drive C is Blade
 Volume Serial Number is B83C-EF1B

 Directory of C:\Users\radix\foo

05/17/2018  08:46 PM    <DIR>          .
05/17/2018  08:46 PM    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  275,911,991,296 bytes free

C:\Users\radix>dir /a foo
 Volume in drive C is Blade
 Volume Serial Number is B83C-EF1B

 Directory of C:\Users\radix\foo

05/17/2018  08:46 PM    <DIR>          .
05/17/2018  08:46 PM    <DIR>          ..
05/17/2018  08:46 PM    <DIR>          .git
               0 File(s)              0 bytes
               3 Dir(s)  275,866,763,264 bytes free
Run Code Online (Sandbox Code Playgroud)

DEL 命令没有显示任何错误,但它无法实际删除存储库。

需要注意的是,该rm命令确实会从存储库中删除文件,包括.git目录中的文件。但它将.git目录留在那里。

已经假定.git子目录的“隐藏”性质导致了问题。这是我的实验记录:

PS C:\Users\radix> git init foo
Initialized empty Git repository in C:/Users/radix/foo/.git/
Run Code Online (Sandbox Code Playgroud)

此时,我打开 Windows 资源管理器并导航到该C:/Users/radix/foo目录,并将其重命名.gitgit. 我还右键单击该.git目录并打开“属性”对话框,注意它没有“隐藏”标志。我还导航到该git目录并右键单击打开几个子目录和文件的属性,注意到它们都没有设置“隐藏”标志。

然后我尝试从 powershell 中删除目录:

PS C:\Users\radix> del foo

Confirm
The item at C:\Users\radix\foo has children and the Recurse parameter was not specified. If you continue, all children
will be removed with the item. Are you sure you want to continue?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): a
del : Cannot remove item C:\Users\radix\foo\git: You do not have sufficient access rights to perform this operation.
At line:1 char:1
+ del foo
+ ~~~~~~~
    + CategoryInfo          : PermissionDenied: (git:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemUnAuthorizedAccess,Microsoft.PowerShell.Commands.RemoveItemCommand
del : Directory C:\Users\radix\foo cannot be removed because it is not empty.
At line:1 char:1
+ del foo
+ ~~~~~~~
    + CategoryInfo          : WriteError: (C:\Users\radix\foo:DirectoryInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : DirectoryNotEmpty,Microsoft.PowerShell.Commands.RemoveItemCommand
Run Code Online (Sandbox Code Playgroud)

我确实注意到此层次结构中的几个文件夹被标记为“只读”。那有关系吗?

所以我有两个问题:为什么我不能删除这个文件夹,为什么 git 以一种不能首先删除它的方式创建它?如果问题是目录是只读的,为什么 git 将它们创建为只读?

Bob*_*Bob 13

我将从解决更简单的情况开始:del在 cmd 中永远不会做你想做的事,因为它只删除files。即便如此,没有/s它也不会递归,只会删除顶级目录中的文件。

因此,对于 cmd,您应该使用rmdir /s递归删除所有文件和文件夹。添加/q是否要禁用确认提示。


现在,PowerShell。Remove-Item(这是什么rmdel别名) with just-Recurse不会递归到隐藏目录,因此不会删除它们的内容。这会导致您的错误 - 这不是“权限被拒绝”而是“目录非空”。

为了解决这个问题,您可以传递-Force参数(相当于 *nix -f)。所以rm -r -forceRemove-Item -Recurse -Force应该工作。

我不完全确定您是如何获得非隐藏.git目录的 - GfW(诚然是较旧的 2.9.2)为我创建了隐藏目录。在cmd中,运行attrib .git以检查它是否隐藏。一旦取消隐藏,一个Remove-Item -Recurse没有-Force.