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)?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Gábor Domonkos
  • 1,081
  • 1
  • 17
  • 33
  • 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? – Philip Pittle Aug 28 '14 at 13:21
  • I added more information to the question. – Gábor Domonkos Aug 28 '14 at 14:10
  • 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. – Philip Pittle Aug 28 '14 at 14:25

2 Answers2

27

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);
}
AJ Richardson
  • 6,610
  • 1
  • 49
  • 59
  • 3
    Thanks, that was my issue too. I you don't want to use recursive method use can also use code from [this](http://stackoverflow.com/a/8714329/350384) answer. – Mariusz Pawelski Oct 16 '15 at 09:00
  • Thanks! Found your answer being almost desperate, it saved me from spending days for rewriting my app to utilize TMP folders for git repos! ^_^ – Alen Pelin May 29 '16 at 20:04
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?

nulltoken
  • 64,429
  • 20
  • 138
  • 130