Получить изменения между коммитом и его родителем с помощью libgit2sharp - PullRequest
8 голосов
/ 03 февраля 2012

Я работаю с 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 в файле Commit.cs libgit2sharp).

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

1) Начните с thЖелаемая фиксация, переход по дереву и сохранение всех значений SHA в наборе.

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

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

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

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

Спасибо.

1 Ответ

8 голосов
/ 04 февраля 2012

Что вам нужно, функция дерева , уже существующая в libgit2 , как определено в tree.h header .

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

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

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

Ссылка:

  • Функция git_tree_diff() реализована в src / tree.c
  • Доступны тесты, использующие эту функцию здесь

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

UPDATE

Релиз v0.9.0 LibGit2Sharp, в конечном счете, привнес функцию разграничения дерева в дерево.

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

Выставленные свойства:

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

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

...