【问题标题】:Wait until Commit-Operation is finished等到提交操作完成
【发布时间】:2014-04-23 11:23:42
【问题描述】:

我在将提交过程与 LibGit2Sharp 同步时遇到问题。 我有一个例程可以更改一个文件并将其提交到 Git 中。该例程可能会快速连续出现。还有一个问题,当最后一次提交正在运行时,下一个提交例程正在运行并因 EmptyCommitException 而崩溃。

这是一个简单的例子:

         for (int i = 0; i < 100; i++)
        {
            using (StreamWriter sw = new StreamWriter(@"...\Test3.txt", false))
            {
                sw.WriteLine(Guid.NewGuid().ToString());
            }
            repo2.Index.Stage(@"...\Test3.txt");
            repo2.Commit("new"); //2nd call crashes with EmptyCommitException
        }

有没有办法等待完成最后一次提交?

我试过用这个:

while (repo2.Info.CurrentOperation != CurrentOperation.None)
{ }

但第一次它不起作用,第二次主动等待不是最好的策略

【问题讨论】:

  • Commit 方法返回什么?
  • 该函数调用 Git 中的 Commit-Function,如果有效则返回新的 Commit。对不起,我忘了写我使用 LibGit2Sharp-Library :-(

标签: c# .net git libgit2sharp


【解决方案1】:

repo.Index.Stage(filePath) 方法在工作目录和索引之间进行比较,以检测传递的filePath 是否应该添加到索引中或从索引中删除。如果未检测到更改,则不会修改索引。

但是,如果文件在同一秒内被修改而文件大小没有变化,那么在 libgit2 中实际实现差异算法的方式可能不会注意到内容变化。一些工作已开始支持基于纳秒的时间戳检查(请参阅 this libgit2 commit)。

因此,由于代码在紧密循环中执行,对Stage() 的第二次调用将不会修改索引,因为它在同一秒内运行而没有修改文件的大小。

然后,当实际尝试创建 Commit 时,会抛出 EmptyCommitException,因为代码检测到正在创建的提交将与其父级在内容方面相同(请参阅 Pull Request #668 引入了这种行为)。

为了解决此限制,您可以:

  • 在循环中引入暂停(例如Thread.Sleep()
  • 直接在对象数据库中创建提交,无需利用索引,手动创建提交(有关此功能的更多详细信息,请参阅此 StackOverflow answer

考虑到您的场景不需要任何用户交互,我会推荐第二种解决方案。

【讨论】:

  • 用户交互的索引。如果没有用户以同步的方式查看它,那么您应该采用第二种解决方案。
  • FWIW 我创建了问题 #688 来跟踪这个亚秒级的更改检测请求
  • 我已经用偷偷摸摸的 2nd Repository-Instance 尝试了 first Option。它工作正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
相关资源
最近更新 更多