Дождитесь завершения Commit-Operation

у меня проблема с синхронизацией процесса фиксации с 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)
{ }

Но 1-е не работает, а 2-е активное ожидание - не лучшая стратегия.


person user3541236    schedule 23.04.2014    source источник
comment
Что возвращает метод Commit?   -  person Sriram Sakthivel    schedule 23.04.2014
comment
Функция вызывает Commit-Function в Git и возвращает новый Commit, если он работает. Извините, я забыл написать, что использую LibGit2Sharp-Library :-(   -  person user3541236    schedule 23.04.2014


Ответы (1)


Метод repo.Index.Stage(filePath) выполняет сравнение между рабочим каталогом и индексом, чтобы определить, должен ли переданный filePath быть добавлен в индекс или удален из него. Если изменений не обнаружено, индекс не изменяется.

Однако то, как алгоритм сравнения фактически реализован в libgit2, может не заметить изменения содержимого, если файл модифицируется в течение той же секунды без изменения его размера. Начата некоторая работа по поддержке проверки временных меток на основе наносекунд (см. эту фиксацию libgit2).

Таким образом, поскольку код выполняется в тесном цикле, второй вызов Stage() не изменит индекс, поскольку он выполнялся в течение той же секунды без изменения размера файла.

Затем, при фактической попытке создать Commit, выдается EmptyCommitException, поскольку код обнаружил, что создаваемый коммит будет идентичен по содержанию своему родительскому элементу (см. Pull Request #668, который представил это поведение).

Чтобы обойти это ограничение, вы можете:

  • Введите паузу (например, Thread.Sleep()) в свой цикл
  • Создавайте коммиты вручную без использования индекса, создавая их напрямую в базе данных объектов (см. этот ответ StackOverflow<) /strong> для получения более подробной информации об этой функции)

Учитывая ваш сценарий, который не требует взаимодействия с пользователем, я бы рекомендовал второе решение.

person nulltoken    schedule 23.04.2014
comment
Индекс взаимодействия с пользователем. Если пользователь не смотрит на него в режиме синхронизации, вам следует выбрать второе решение. - person Carlos Martín Nieto; 23.04.2014
comment
FWIW Я создал задачу #688, чтобы отслеживать это запрос обнаружения изменений менее чем за секунду - person nulltoken; 23.04.2014
comment
Я попробовал первый вариант со скрытым вторым экземпляром репозитория. Это работает нормально. - person user3541236; 24.04.2014