Repository.Stage(“*”)抛出ObjectDisposedException

时间:2015-05-19 23:46:09

标签: c# git libgit2sharp

我将git存储库下的所有文件暂存以进行提交,提交更改,然后检查更改并修改提交,更改其消息。看看我的代码:

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)

在我的插件的init方法中没有发布,我有一行定义变量 repository。它是: this.repository = new Repository(Repository.Init) (this.gameDirectory));

你们发现我的代码有什么问题吗?

1 个答案:

答案 0 :(得分: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处理后调用方法。