2015-05-19 2 views
0

Я обрабатываю все файлы в репозитории git для фиксации, фиксации изменений, затем проверяю изменения и исправляет коммит, изменяя его сообщение. Взгляните на мой код:Repository.Stage ("*") выбрасывает ObjectDisposedException

if (this.isRepoInit) // Check if the repository has been initialized successfully 
     { 
      using (Repository repo = repository) 
      { 
       // Stage all files 
       repo.Stage("*"); 

       // Setup the commit author 
       Signature author = new Signature(this.userData.AuthorName, this.userData.AuthorEmail, DateTime.UtcNow); 
       Commit currCommit = repo.Commit("Temporary commit message", author); 


       // Write our commit message 
       StringBuilder sb = new StringBuilder(); 

       Tree commitTree = repo.Head.Tip.Tree; 
       Tree parentCommitTree = repo.Head.Tip.Parents.Single().Tree; 

       TreeChanges changes = repo.Diff.Compare<TreeChanges>(parentCommitTree, commitTree); 
       if (changes.Count() > 0) 
       { 
        string pluralFile = "file"; 
        string pluralInsertion = "insertion"; 
        string pluralDeletion = "deletion"; 
        if (changes.Count() != 1) pluralFile = "files"; 
        if (changes.Added.Count() != 1) pluralInsertion = "insertions"; 
        if (changes.Deleted.Count() != 1) pluralDeletion = "deletions"; 

        sb.AppendLine(string.Format("{0} {1} changed, {2} {3}(+), {4} {5}(-)", 
         changes.Count(), pluralFile, changes.Added.Count(), pluralInsertion, changes.Deleted.Count(), pluralDeletion)); 

        CommitOptions commitOptions = new CommitOptions() 
        { 
         AmendPreviousCommit = true, 
         AllowEmptyCommit = false, 
         PrettifyMessage = true, 
         CommentaryChar = '#' 
        }; 

        // Try to commit. If it throws, we log it. 
        try 
        { 
         Commit ammendedCommit = repo.Commit(sb.ToString(), author, commitOptions); 
         Logger.Debug("Committed changes, id: " + ammendedCommit.Sha); 
        } 
        catch (EmptyCommitException) 
        { 
         Logger.Debug("Nothing changed. Skipping commit."); 
        } 
        catch (Exception e) 
        { 
         Logger.LogError("Error while committing: {0}", e.Message); 
        } 
       } 
      } 
     } 

Я не знаю, что здесь происходит. Это CallStack, если кто-то хочет:

[Edit] ERROR: An error occurred: ObjectDisposedException at Void SafeHandle.DangerousAddRef(Boolean&): Safe handle has been closed 
      CallStack: 
       at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success) 
       at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success) 
       at LibGit2Sharp.Core.NativeMethods.git_diff_index_to_workdir(DiffSafeHandle& diff, RepositorySafeHandle repo, IndexSafeHandle index, GitDiffOptions options) 
       at LibGit2Sharp.Core.Proxy.git_diff_index_to_workdir(RepositorySafeHandle repo, IndexSafeHandle index, GitDiffOptions options) 
       at LibGit2Sharp.Diff.BuildDiffList(ObjectId oldTreeId, ObjectId newTreeId, TreeComparisonHandleRetriever comparisonHandleRetriever, DiffModifiers diffOptions, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) 
       at LibGit2Sharp.Diff.Compare[T](DiffModifiers diffOptions, IEnumerable`1 paths, ExplicitPathsOptions explicitPathsOptions, CompareOptions compareOptions) 
       at LibGit2Sharp.Repository.Stage(IEnumerable`1 paths, StageOptions stageOptions) 

О методе инициализации моего плагина, который не разместил здесь, у меня есть строка, которая определяет переменную хранилище. Это: this.repository = новый репозиторий (Repository.Init (this.gameDirectory));

Возможно, вы нашли что-то в своем коде?

ответ

2

Почему вы обертываете это в using? Это пахнет ошибкой. Если вы используете этот шаблон в другом месте, вы бы выбрали хранилище.

Например, если вы выполняете:

this.repository = new Repository(); 

using (var repo = repository) 
{ 
    // do something 
} 

using (var repo = repository) 
{ 
    // do something else 
} 

Тогда вы получите исключение во втором блоке, потому что вы пытаетесь использовать хранилище после того, как вы распорядились его, в силу выхода первой using блок.

Не обертывайте их в блоки using. Просто выполните работу с this.repository и удалите ее, когда вы закончите, и ваш плагин выйдет.

В качестве альтернативы вы можете создать свой класс IDisposable и разместить экземпляр своего репозитория в методе dispose.

Однако вы это сделаете, не вызывайте методы на IRepository после того, как вы уже разместили его.

Смежные вопросы