Programmatically delete local repository with LibGit2Sharp
Asked Answered
W

2

9

I would like to delete the local repo folder that I cloned from remote repository using LibGit2Sharp. I read here here that I have to Dispose() the Repository before I can delete it, but it still not works fine.

using (var repo = new LibGit2Sharp.Repository(path))
{
    repo.Dispose();
}

Directory.DeleteFolder(path);

And I still have an exception:

Access to the path 'c16566a7-202a-4c8a-84de-3e3caadd5af9' is denied.

The content of the 'path' variable is the following:

 C:\Users\USERNAME\AppData\Local\dftmp\Resources\c16566a7-202a-4c8a-84de-3e3caadd5af9\directory\UserRepos\github.com\domonkosgabor\testrepo

This folder was created by a worker role to a local storage.

What should I do to delete the whole folder (including .git)?

Whitelivered answered 28/8, 2014 at 13:7 Comment(4)
Your path folder has a Guid, not a folder path. Where is it coming from? Also, I read here that I have to Dispose() Where is here? Did you forget a link?Fagen
I added more information to the question.Lunalunacy
Two things: 1) Are you executing this code with enough privlidges (ie as an Administrator?) 2) Add the code if (Directory.Exists(path)) before the DeleteFolder code to make sure the directory is actually there.Fagen
While the "Dispose" answer was accepted, I would urge anyone with access issues to look at the other answer regarding read-only files. This seems to be the far more likely issue for many.Unsecured
A
2

I would like to delete the local repo folder that I cloned from remote repository using LibGit2Sharp. I read here here that I have to Dispose() the Repository before I can delete it.

LibGit2Sharp keeps hold on some files in the .git folder (mainly the packfiles for performance reasons). Calling Dispose() will release those handles and deallocate the non managed memory.

As such, it's indeed a strong recommendation to rely on the using statement (or, at the very least to Dispose() the Repository instance when you're done with it).

If you don't do this, those handles will eventually be released through finalizers when your AppDomain has unloaded, but you will have no real control regarding "when" that's going to happen.

Edit: Reading your code once again, I overlooked something. The recommended pattern is either

using (var repo = new LibGit2Sharp.Repository(path))
{
    // Do amazing stuff
}

or

var repo = new LibGit2Sharp.Repository(path);
// Do amazing stuff
repo.Dispose();

Indeed, the using statement will automatically issue a call to Dispose() once the code reach the end of the scope.

Access to the path 'c16566a7-202a-4c8a-84de-3e3caadd5af9' is denied.

Regarding this point, I think this has nothing to do with LibGit2Sharp.

Is the process (trying to delete the folder named after a guid) running under an identity granted with enough rights to do so?

Achernar answered 28/8, 2014 at 15:9 Comment(1)
You are correct, the Dispose() method works fine, I have not enough rights to delete the folder. Thank you very much!Lunalunacy
P
28

For the benefit of anyone else having this problem:

I had the same problem, but I was still getting an UnauthorizedAccessException even though I was running as administrator, and I was disposing the repository object correctly. It turns out that some of the files in the .git folder are marked as ReadOnly, so I had to loop through each file and remove the ReadOnly attribute before deleting. I wrote a custom method to do this:

/// <summary>
/// Recursively deletes a directory as well as any subdirectories and files. If the files are read-only, they are flagged as normal and then deleted.
/// </summary>
/// <param name="directory">The name of the directory to remove.</param>
public static void DeleteReadOnlyDirectory(string directory)
{
    foreach (var subdirectory in Directory.EnumerateDirectories(directory)) 
    {
        DeleteReadOnlyDirectory(subdirectory);
    }
    foreach (var fileName in Directory.EnumerateFiles(directory))
    {
        var fileInfo = new FileInfo(fileName);
        fileInfo.Attributes = FileAttributes.Normal;
        fileInfo.Delete();
    }
    Directory.Delete(directory);
}
Polyphonic answered 14/10, 2014 at 23:26 Comment(3)
Thanks, that was my issue too. I you don't want to use recursive method use can also use code from this answer.Referee
Thanks! Found your answer being almost desperate, it saved me from spending days for rewriting my app to utilize TMP folders for git repos! ^_^Bangtail
THIS is the root cause of getting access exceptions deleting the local repo. I have been spending the better part of a day trying to figure this out. Thank you, AJ!Unsecured
A
2

I would like to delete the local repo folder that I cloned from remote repository using LibGit2Sharp. I read here here that I have to Dispose() the Repository before I can delete it.

LibGit2Sharp keeps hold on some files in the .git folder (mainly the packfiles for performance reasons). Calling Dispose() will release those handles and deallocate the non managed memory.

As such, it's indeed a strong recommendation to rely on the using statement (or, at the very least to Dispose() the Repository instance when you're done with it).

If you don't do this, those handles will eventually be released through finalizers when your AppDomain has unloaded, but you will have no real control regarding "when" that's going to happen.

Edit: Reading your code once again, I overlooked something. The recommended pattern is either

using (var repo = new LibGit2Sharp.Repository(path))
{
    // Do amazing stuff
}

or

var repo = new LibGit2Sharp.Repository(path);
// Do amazing stuff
repo.Dispose();

Indeed, the using statement will automatically issue a call to Dispose() once the code reach the end of the scope.

Access to the path 'c16566a7-202a-4c8a-84de-3e3caadd5af9' is denied.

Regarding this point, I think this has nothing to do with LibGit2Sharp.

Is the process (trying to delete the folder named after a guid) running under an identity granted with enough rights to do so?

Achernar answered 28/8, 2014 at 15:9 Comment(1)
You are correct, the Dispose() method works fine, I have not enough rights to delete the folder. Thank you very much!Lunalunacy

© 2022 - 2024 — McMap. All rights reserved.