Получите изменения между коммитом и его родителем с помощью libgit2sharp

Я работаю с libgit2sharp (обертка C# для libgit2) и сталкиваюсь с проблемами, потому что у него нет многих функций, на которые я надеюсь (надеюсь, я смогу внести свой вклад в него в ближайшее время; это кажется действительно полезным проектом)

То, что я пытаюсь сделать прямо сейчас, — это получить список файлов, измененных из определенного коммита и его родителя. Я не буду пытаться выяснить, что изменилось между слиянием и двумя его родителями. Меня больше интересуют регулярные коммиты.

Эти ребята (https://github.com/libgit2/libgit2sharp/issues/89) работают над чем-то подобным. Я думаю, что их процедура - здравая идея, но я немного слаб в своем понимании внутреннего устройства GIT (в руководстве конечного пользователя по GIT есть множество руководств, но не так много по внутренней структуре)

Мне любопытно, как сам GIT выполняет команду «git diff». Предположительно, GIT на самом деле хранит не дельты, а полную версию файла (если он не изменился, он просто укажет на существующий SHA. Эту информацию можно найти из различных источников, таких как здесь http://xentac.net/2012/01/19/the-real-difference-between-git-and-mercurial.html). Кажется, это усложняет получение изменений между двумя фиксациями (в моем случае конкретной фиксацией и ее единственным родителем), потому что данные не хранятся как часть фиксации (что становится ясно, если вы изучите класс Commit в libgit2sharp Commit.cs). файл).

К чему я могу получить доступ из коммита, так это к дереву. Имеет ли смысл сделать следующее, чтобы найти эту информацию:

1) Начните с нужного коммита, пройдитесь по дереву и сохраните все значения SHA в наборе.

2) Начните с родителя для нужного коммита и пройдите вниз по его дереву, чтобы сохранить все его значения SHA больших двоичных объектов в другом наборе.

3) SHA для измененных файлов будут файлами, которые не находятся на пересечении двух наборов.

Проблема, которую я вижу с этим подходом, заключается в том, что не похоже, что есть способ получить имя файла из значения SHA блоба (я не вижу ничего, что могло бы сделать это в файле libgit2sharp Blob.cs).

Я знаю, что у этого вопроса много аспектов, но они являются частью этой большой цели — получить определенный фрагмент данных из git.

Спасибо.


person bashirs    schedule 03.02.2012    source источник
comment
Помните, что на один и тот же Blob через его SHA будут указывать разные TreeEntries с разными именами файлов. Это произойдет, когда файлы будут иметь одинаковое содержимое.   -  person nulltoken    schedule 03.02.2012


Ответы (1)


То, что вам нужно, функция различения деревьев, уже существует в libgit2. как определено в заголовок tree.h.

Функция git_tree_diff() сравнивает два Trees и вызывает обратный вызов для каждого различия (добавление, обновление и удаление). В функцию обратного вызова передается структура git_tree_diff_data с путем к файлу рассматриваемого большого двоичного объекта, его статусом, прежним и текущим файловыми режимами, а также прежним и текущим SHA.

С точки зрения LibGit2Sharp было бы разумнее использовать существующие функции libgit2, чем повторно реализовывать их на C#. Однако, даже если вы можете черпать вдохновение из существующих Interop определений, при попытке укротить уровень взаимодействия .Net/native все становится очень сложно.

С вашей точки зрения (поскольку участие в LibGit2Sharp может не быть вашей основной целью ;)), еще один вариант — перенести код C на C#, полагаясь на существующие функции LibGit2Sharp для работы вниз по деревьям. git_tree_diff() (и его сопутствующие функции) — очень чистый фрагмент кода, и хотя он выполняет довольно сложную работу, комментарии очень понятны и полезны.

Ссылки:

Примечание. Чтобы связать git_tree_diff(), задача должна быть открыта в трекер libgit2 запрашивает обновление определения метода, чтобы оно было GIT_EXTERN. В противном случае он не будет доступен из .Net.

ОБНОВИТЬ

В выпуске v0.9.0 LibGit2Sharp в конечном итоге появилась функция сравнения дерева с деревом.

TreeChanges changes = repo.Diff.Compare(fromTree, newTree);

Открытые свойства:

  • Добавлены/изменены строки
  • Коллекции изменений TreeEntry для каждого типа изменений (например, добавлено, изменено, ...)
  • Патч diff

Вы можете узнать больше об этой функции и о том, как использовать TreeChanges, взглянув на модульные тесты в DiffTreeToTreeFixture.cs.

person nulltoken    schedule 03.02.2012
comment
Большое спасибо за отличный ответ! Я заметил, что вы являетесь активным участником как libgit2, так и libgit2sharp. Я очень заинтересован в том, чтобы помочь с этим проектом, поэтому я посмотрю, смогу ли я использовать функцию libgit2 в libgit2sharp. Хотя я не знаю, ищет ли какой-либо проект другого участника. - person bashirs; 04.02.2012