Repository.Stage("*") 抛出 ObjectDisposedException
Repository.Stage("*") throws an ObjectDisposedException
我暂存 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);
}
}
}
}
我不知道这里发生了什么。这是调用堆栈,如果有人需要的话:
[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 = 新存储库(Repository.Init(this.gameDirectory));
你们能发现我的代码有什么问题吗?
为什么要将它包装在 using
中?这闻起来像一个错误。如果您在其他地方使用此模式,那么您将处理存储库。
例如,如果您正在表演:
this.repository = new Repository();
using (var repo = repository)
{
// do something
}
using (var repo = repository)
{
// do something else
}
然后你会在第二个块中得到一个异常,因为你试图通过退出第一个 using
块来使用存储库。
不要将它们包装在 using
块中。只需针对 this.repository
进行工作,并在完成后将其处理掉,然后您的插件就会退出。
或者,您可以创建 class IDisposable
并在 dispose
方法中配置存储库实例。
无论您如何操作,都不要在 IRepository
已经处置后调用方法。
我暂存 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);
}
}
}
}
我不知道这里发生了什么。这是调用堆栈,如果有人需要的话:
[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 = 新存储库(Repository.Init(this.gameDirectory));
你们能发现我的代码有什么问题吗?
为什么要将它包装在 using
中?这闻起来像一个错误。如果您在其他地方使用此模式,那么您将处理存储库。
例如,如果您正在表演:
this.repository = new Repository();
using (var repo = repository)
{
// do something
}
using (var repo = repository)
{
// do something else
}
然后你会在第二个块中得到一个异常,因为你试图通过退出第一个 using
块来使用存储库。
不要将它们包装在 using
块中。只需针对 this.repository
进行工作,并在完成后将其处理掉,然后您的插件就会退出。
或者,您可以创建 class IDisposable
并在 dispose
方法中配置存储库实例。
无论您如何操作,都不要在 IRepository
已经处置后调用方法。