Всем привет.
Я ищу метод, который вернет последнюю фиксацию, затронувшую данный файл.
Я просмотрел API, но не нашел метода, который, похоже, это делает.
Первый вопрос: было ли решение упущено из виду?
Второй вопрос: как получить последний коммит?
Спасибо.
@Флоникс ,
Привет. Похоже, вы после чего-то вроде git log -1 --follow FILENAME
Первый вопрос: было ли решение упущено из виду?
Нет. Это еще не реализовано.
Второй вопрос: как получить последний коммит?
Очень просто. Это двухэтапный процесс:
Шаг первый:
Шаг второй:
@nulltoken ,
Это именно то, что я ищу.
Я надеялся, что это уже реализовано...
посмотрю через несколько дней. Может быть, я могу решить это.
Спасибо пока...
Привет, @Flonix , пожалуйста, взгляни на нашу дискуссию с @nulltoken на StackOverflow . Я планирую реализовать подход, который я упоминал там, и поделиться с вами Gist .
Привет, @shytikov ,
так что у нас одинаковые намерения ;-)
В настоящее время я читаю (и заканчиваю) свою книгу GIT. У меня были некоторые пробелы в отношении внутренних записей GIT Tree и Blob.
Пожалуйста, дайте мне знать, когда вы начнете внедрять.
Я надеюсь, что у меня будет время реализовать (неудачный) тест в течение следующих нескольких дней.
Некоторые самые первые мысли об API:
Commit startCommit
, определяет, с чего начать обход историиstring filePath
определяет, какой файл мы будем искатьint maxCommits
, определяет, когда остановить обход историиmaxCommits
Все еще отсутствует: хорошее имя для имени метода...
@Flonix , @nulltoken
Я провел вечер, анализируя код (это было чудесное время, правда!) и задал вам следующие вопросы:
Я сильно запутался, так как обновление метода QueryBy приводит либо к уродливому коду (реализация IEnumerable просто передает вызовы C-бэкэнду, и изменить его поведение под наши нужды будет сложно), либо обновление IndexEntry сделает libgit2sharp не таким тонким прокси к бэкэнду C...
Можете ли вы поделиться своей мыслью?
Ааа!!!
Кто-то сказал: «Независимо от того, насколько крут ваш код, вам будет стыдно, что вы написали его шесть месяцев спустя». Это относится и к сообщениям в системе отслеживания проблем. За исключением того, что вы чувствуете стыд намного быстрее :)
Мы получили класс RepositoryExtensions !!! Идеальное место для такого кода!
@шитиков , @nulltoken
Я думаю, мы должны сделать libgit2sharp как можно тоньше.
Но это не исключает, что нам придется обновлять/модифицировать и libgit2sharp...
Я не уверен, есть ли у libgit2 какая-то поддержка history walking
. Я еще не очень хорошо знаком с кодом libgit2.
Так что я должен взглянуть на него...
@Flonix , у него есть revison walking
API, позволяющий вам ограничить коллекцию коммитов _date_, _branch_, _tag_ и, возможно, чем-то еще. Но не _имя_файла_.
Как я понял из ответа @nulltoken , можно «предварительно ограничить» выбор фиксации на revison walking
, а затем выполнить поиск в этой коллекции, например, с помощью _Linq_.
На данный момент я не думаю, что смогу придумать код C, ограничивающий выбор коммитов по имени файла (нужно потратить некоторое время на взлом libgit2), но легко добавить новый метод _ViewHistory_ в класс RepositoryExtensions .
Является ли этот подход способом libgit2sharp?
@Flonix , пожалуйста, взгляните на первый черновик в этой сути
Работа все еще продолжается, так как она не соответствует файлу, если он был переименован и изменен в том же коммите. И ти не в счет модификаций.
@шитиков ,
некоторые очень простые мысли после очень короткого взгляда на ваш код:
(Если коммитов больше, чем n
, вы можете начать дальнейший поиск с последнего коммита в результате, поэтому вам не нужно просматривать уже найденные коммиты...)
Вопрос 1 : Да, вы проходите через все коммиты, но упорядочены ли они?
Вопрос 2 : Не уверен, что насчет слияний...
Это зависит от вопроса 1...
Если они заказаны... Какой коммит-родитель будет взят для продолжения поиска?
Если они не заказаны... Возможно, нам придется их заказать ;-)
@Flonix , спасибо!
Остается много открытых вопросов, и они в основном касаются бэкэнда C...
Для ускорения кода нужно сделать две вещи:
maxCommits
;Что касается упорядочивания коммитов... Это легко сделать, используя следующий синтаксис:
foreach (Commit c in repository.Commits.QueryBy(filter))
{ ... }
Но это означает, что нам нужно передать методу filter
. И поскольку я вижу дизайн libgit2sharp, было бы лучше реализовать это как часть Filter . Добавьте в этот класс еще два поля: IndexEntry (объект, содержащий как SHA, так и путь к файлу) и MaxCommits , чтобы ограничить их количество. И сделать результаты зависимыми от их значений.
Но чтобы сделать это правильно, нам нужно изменить код C, потому что IQueryableCommitCollection
довольно тесно связан с нативными вызовами.
Что касается слияний, я не знаю... это определенно стоит проверить :)
@Flonix , @nulltoken ,
не могли бы вы посоветовать мне, как пропустить слияния при получении истории коммитов для файла. Кажется, SHA файла меняется, хотя на самом деле он не менялся. Есть ли общий подход к этому? Я не хочу запускать двоичное сравнение для файловых BLOB-объектов...
@Flonix , сегодня утром один «приятный» сюрприз: код, который я написал, недействителен для файлов, хранящихся в подпапках :) Объект « Дерево» содержит файлы только из корневой папки. Для просмотра других папок нам нужно проанализировать коллекцию деревьев, прикрепленных к текущему дереву! :здорово:
@шитиков
Да это правда. Для каждого (под)каталога существует одно дерево.
Вчера вечером я просмотрел код C libgit2. Реализована своего рода ревизионная ходьба.
На выходных посмотрю поближе.
@Flonix , я тоже хакаю. На данный момент я обнаружил, что можно _скрыть_ пакет коммитов от возврата пользователю. Но перед этим система должна определить список коммитов, в которых данный файл не изменялся, и передать эту информацию в качестве аргумента.
С нетерпением жду ответа от вас в понедельник.
@Flonix , я поднял этот вопрос в системе отслеживания проблем libgit2 .
@Flonix @shytikov Вау, эта ветка занята :)
Чтобы убедиться, что мы разделяем общее понимание, я настроил репозиторий для быстрого тестирования @ https://github.com/nulltoken/follow-test . Вики-страница описывает некоторые возможные варианты использования. Не стесняйтесь добавлять свои.
Как только вы получите, что код фильтрации C# возвращает правильные коммиты, было бы неплохо переупаковать его в метод CommitCollection.QueryBy() .
В конце концов, с точки зрения API, имя файла должно быть дополнительным необязательным свойством типа фильтра . Тестовый репозиторий будет перемещен в репозиторий LibGit2Sharp в каталоге Resources
.
Пингуйте меня, если вам нужна помощь.
@шитиков
Каков ваш текущий статус?
Вы что-то реализовали?
@Flonix да, я взламываю внутренности git. Я пытаюсь понять, как я могу получить необходимую информацию из репозитория Git. На самом деле это превратилось для меня в большое развлечение: https://github.com/toolchain/IronGit (не бойтесь: это пока код качества пре-альфа).
Как только пойму, какой оптимальный способ создать журнал по имени файла, я интегрирую его в libgit2sharp
.
@yorah Я не уверен, но я думаю, что Diff API может облегчить выполнение этой задачи ... Однако нам может понадобиться статус «Переименовано / Скопировано». Каково твое мнение?
Новичок во всем этом git, но начал работать над этими проблемами, чтобы изучить libgit2sharp. Не завершено/не прокомментировано/и т. д., но соответствует 2 из 3 вариантов использования в вариантах использования @nulltoken для последующего тестирования.
https://github.com/salerth/libgit2sharp/tree/follow
(Я должен добавить, что на данный момент у меня есть консольное приложение в качестве тестовой системы... оно уйдет, когда я проведу несколько тестов!)
Всем привет,
Были ли какие-либо разработки по этой функции? Где мы с этим. Если у меня будет время на этой/следующей неделе, я не против собрать что-нибудь вместе.
С уважением,
Фолкон
Привет @Folcon ,
Были ли какие-либо разработки по этой функции?
Хотя это обязательно произойдет в какой-то момент, libgit2 не реализует эту функцию.
Где мы с этим.
По этой теме ничего не объединено
Если у меня будет время на этой/следующей неделе, я не против собрать что-нибудь вместе.
Удивительный!
Меня отвлекли рабочие проекты, поэтому я так и не закончил это. В итоге он в основном работал, включая процент разницы в файлах для обнаружения переименования.
@nulltoken Спасибо за обновления.
@salerth Я предполагаю, что это здесь? https://github.com/salerth/libgit2sharp/tree/follow.
@Folcon Да, действительно, в основном в LibGit2Sharp/RepositoryExtensions.cs
Всем привет,
Извините, что я исчезла там, у меня наконец-то появилось немного времени на этой неделе, и я посмотрю на вещи, как я сказал ранее.
С уважением,
Фолкон
Всем привет,
Итак, я потратил некоторое время на просмотр всего, что здесь есть.
@salerth Какой вариант использования вам не хватает? Ваш вывод для последующего теста соответствует ожидаемым результатам @nulltoken https://github.com/nulltoken/follow-test/wiki .
Кажется, что вы это сделали, по крайней мере, на первый взгляд. Я собираюсь провести еще несколько тестов, чтобы убедиться, что это работает так, как я ожидаю, но где вы видели сбой? В противном случае максимум, что я могу предложить, это немного почистить его;)...
С уважением,
Фолкон
Привет, ребята,
Если вы чувствуете, что сейчас подходящий момент, как насчет того, чтобы перебазировать его на последнюю версию vNext
, перенести тестовые примеры на фикстуру xUnit (может быть, FollowFixture.cs
?) и открыть PR?
У меня нет проблем с этим, я хотел бы, чтобы @salerth перезвонил на всякий случай, если мы пропустили какой-то вариант использования?
Нет, насколько мне известно, он работал во всех вариантах использования, которые я мог использовать. Все, что я оставил в своем списке дел для этого, — это модульные тесты, затем очистка, проверка того, что все в нужном месте и т. д. Я также пробовал только с довольно небольшими репозиториями, поэтому не был уверен в производительности на гораздо большей истории.
В основном я хотел, чтобы кто-то просто просмотрел его, так как я впервые столкнулся с внутренностями git, поэтому не был уверен, что это лучший способ снять шкуру с этого конкретного кота.
На самом деле мне интересно, есть ли способ обновить объект репо перед просмотром истории? Если это уже не происходит?
Я получаю сообщение "сгенерировать новое исключение LibGit2SharpException(String.Format("Не удается найти файл с именем "{0}" в текущем индексе.", filePath));" если репо недавно было обновлено в файловой системе, когда вызывается команда истории, и я не уверен, что это не вызвано устаревшим объектом, если это возможно? Это единственное объяснение, которое приходит на ум. Начну упаковывать код :)...
В основном индекс устарел, он не содержит записей о вновь добавленных объектах, хотя они и появляются в коммитах.
Кто-нибудь реализовал оригинальную функцию, о которой просил @Flonix ? Если нет, то я хотел бы помочь. Мне это тоже нужно.
Кто-нибудь реализовал оригинальную функцию, о которой просил @Flonix ? Если нет, то я хотел бы помочь. Мне это тоже нужно.
@ nmartin867 Не то, чтобы я знал.
@Folcon Похоже, мы можем извлечь выгоду из встроенной поддержки работы @arrbee в libgit2. См. этот комментарий для получения дополнительной информации.
Следующий код может получить последнюю фиксацию, которая изменила GitObject, а также Blob/Tree/GitLink.
using (var repo = new Repository(@"path\to\libgit2"))
{
var path = @"src/blob.c";
var commit = repo.Head.Tip;
var gitObj = commit[path].Target;
var set = new HashSet<string>();
var queue = new Queue<Commit>();
queue.Enqueue(commit);
set.Add(commit.Sha);
while (queue.Count > 0)
{
commit = queue.Dequeue();
var go = false;
foreach (var parent in commit.Parents)
{
var tree = parent[path];
if (tree == null)
continue;
var eq = tree.Target.Sha == gitObj.Sha;
if (eq && set.Add(parent.Sha))
queue.Enqueue(parent);
go = go || eq;
}
if (!go)
break;
}
// output is: 49781a0 Blame: minor cleanup
Console.WriteLine("{0} {1}", commit.Sha.Substring(0, 7), commit.MessageShort);
}
Как обсуждалось на https://github.com/libgit2/libgit2/issues/495 , также мы можем реализовать последнюю выполненную фиксацию для древовидного представления, которое похоже на древовидное представление github.
Я бы предложил реализовать две функции на уровне libgit2, а не на уровне libgit2sharp, потому что libgit2 имеет более эффективный пул объектов, чем libgit2sharp.
Я бы предложил реализовать две функции на уровне libgit2, а не на уровне libgit2sharp, потому что libgit2 имеет более эффективный пул объектов, чем libgit2sharp.
:+1:
Самый полезный комментарий
@Флоникс ,
Привет. Похоже, вы после чего-то вроде
git log -1 --follow FILENAME
Нет. Это еще не реализовано.
Очень просто. Это двухэтапный процесс:
Шаг первый:
Шаг второй: