Question

i have a problem with synchronizing the commitingprocess with LibGit2Sharp. I have a routine that changes one file and commit it in Git. It is possible that the routine comes in quick succession. And there is the Problem, while the last commit is running, the next commit-routine is runs and crashes with an EmptyCommitException.

Here is a simple example:

         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
        }

Is there a way to wait for finishing the last commit?

I've tried to use this:

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

But 1st it isnt working and 2nd active waiting isnt the best strategy

Was it helpful?

Solution

The method repo.Index.Stage(filePath) performs a diff between the working directory and the index in order to detect if the passed filePath is supposed to be added to or removed from the index. When no change is detected, the index isn't modified.

However, the way the diffing algorithm is actually implemented in libgit2 may not notice a content change if the file is modified within the same second without a change in its size. Some work has been started to support a nanosecond based timestamp check (see this libgit2 commit).

Thus, as the code executes in a tight loop, the second call to Stage() will not modify the Index because it ran within the same second without modifying the size of the file.

Then, when actually trying to create a Commit, an EmptyCommitException is thrown as the code detected that the commit being created would be identical content-wise to its parent (see Pull Request #668 which introduced this behavior).

In order to work around this limit, you can either:

  • Introduce a pause (eg. Thread.Sleep()) in your loop
  • Craft your commits by hand without leveraging the index by directly creating them in the object database (See this StackOverflow answer for more details about this feature)

Considering your scenario that doesn't require any user interaction, I would recommend the second solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top