Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Git-Bash for Windows 'rm' work?

Under some circumstances, the rm command in Git-Bash deletes files that can't be deleted in explorer, cmd prompt, PowerShell, or using C++ standard library calls.

Why?

This is perplexing to me because I know there is no magic here and I assume that they are all using the same Win32 API.

For example, I have database snapshots that remain open and cannot be deleted using the other methods described, but are successfully deleted by Git-Bash rm:

Explorer delete: "The action cannot be completed because the file is open."

cmd: del <path> : "Access is denied"

PS: Remove-Item -Force -Path <path> : "Cannot remove item. Access to the path is denied."

C++ remove() : returns -1

C++ unlink() : returns -1

C++ _unlink() : returns -1

git-bash rm <path> : success

The above can be performed repeatedly on different files.

There are other locked files that git-bash rm deletes successfully as well (I have used it in the past, not recently and I don't have other specific examples).

However it doesn't always work: In a test application I opened a text file using fopen() and none of the methods, including Git-Bash rm, could successfully delete it.

So, how does Git-Bash rm work?

like image 460
apamburn Avatar asked Jan 23 '18 02:01

apamburn


People also ask

What does rm do in Git bash?

Git rm Overview The primary function of git rm is to remove tracked files from the Git index. Additionally, git rm can be used to remove files from both the staging index and the working directory. There is no option to remove a file from only the working directory.

How does Git bash on Windows work?

Git Bash is an application for Microsoft Windows environments which provides an emulation layer for a Git command line experience. Bash is an acronym for Bourne Again Shell. A shell is a terminal application used to interface with an operating system through written commands.

Does rm work in Windows?

So yes, you can use the 'rm' command on windows.


1 Answers

I was able to figure out how this works.

Interestingly, I used Git-Bash's strace utility on it's rm command.

It turns out that Git Bash uses CygWin, and the delete routine is found in the CygWin syscalls.cc file which tries to delete a file in a few different ways.

Eventually it tries to move the file to the Recycle Bin, where it deletes the locked file by opening it with the Windows Driver call NtOpenFile() with a FILE_DELETE_ON_CLOSE flag, then closing it using NtClose().

Not sure if it would be proper to copy CygWin's code into the response here, but details on all of the above can be found in the link provided.

like image 65
apamburn Avatar answered Oct 26 '22 20:10

apamburn