web-dev-qa-db-ja.com

Git for Windowsがコマンドラインから削除できないリポジトリを作成するのはなぜですか?

私はWindows 10の「リセット」インストールを新たに実行しました。Gitの「Git for Windows」ディストリビューションを https://git-scm.org/ からインストールしました。

何らかの方法でgitリポジトリを作成した場合(initまたはclone)、そのリポジトリはコマンドラインプロンプトでファイルシステムから削除できません。それには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

これは、通常のユーザーとして実行しているPowerShellです。管理者としてPowershellを実行しても、rm -Recurseコマンドはまったく同じように失敗します。私が知っているこの新しいfooディレクトリを削除する唯一の方法は、Windowsエクスプローラーを使用して削除することです。これにより、アクセス許可について文句を言われたりプロンプトが表示されたりすることはありません。問題なく静かに削除されます。

CMDでも同様の動作が発生するため、これはPowerShell固有の問題だとは思いません。

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

DELコマンドはエラーを表示しませんが、実際のリポジトリの削除に失敗します。

rmコマンドは、.gitディレクトリ内のファイルを含め、リポジトリからファイルを削除することに注意してください。ただし、.gitディレクトリはそのまま残されます。

.gitサブディレクトリの「隠された」性質が問題を引き起こしていると考えられています。これに関する私の実験の筆記録は次のとおりです。

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

この時点で、Windowsエクスプローラを開いてC:/Users/radix/fooディレクトリに移動し、.gitの名前をgitに変更します。また、.gitディレクトリを右クリックして、[非表示]フラグがないことに注意して[プロパティ]ダイアログを開きます。また、gitディレクトリに移動し、いくつかのサブディレクトリとファイルで右クリックしてopen-propertiesを選択します。「非表示」フラグが設定されていないことに注意してください。

そして、私は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

この階層のいくつかのフォルダが「読み取り専用」としてマークされていることに気づきました。それは関連していますか?

だから私は2つの質問があります:なぜこのフォルダを削除できないのですか、そして最初に削除できないようにgitがそれを作成しているのはなぜですか?ディレクトリが読み取り専用であることが問題である場合、gitがそれらを読み取り専用として作成するのはなぜですか?

簡単なケースから始めましょう:cmdのdelfilesを削除するだけなので、望んだことは決してできません。それでも、/sがないと、再帰せず、最上位ディレクトリのファイルのみを削除します。

したがって、cmdの場合、rmdir /sを使用して、すべてのファイルとフォルダーを再帰的に削除する必要があります。確認プロンプトを無効にする場合は、/qを追加します。


さて、PowerShell。 Remove-Itemだけを使用した-Recursermおよびdelのエイリアス)は、隠しディレクトリに再帰しないため、その内容は削除されません。これはあなたのエラーにつながります-これは「アクセスが拒否されました」ではなく、「空ではないディレクトリ」です。

これを回避するには、-Forceパラメータを渡します(* nix -fと同等)。したがって、rm -r -forceまたはRemove-Item -Recurse -Forceが機能するはずです。

非表示ではない.gitディレクトリをどのように取得しているのか、完全にはわかりません-GfW(確かに古い2.9.2)は、それらを非表示として作成します。 cmdでattrib .gitを実行して、非表示かどうかを確認します。非表示を解除すると、Remove-Item -Recurse-Forceなしで機能します。

9
Bob