Git: что такое трансплантат или идентификатор трансплантата?
На http://git-scm.com/docs/git-filter-branch сказано:
Чтобы установить коммит (который обычно находится на вершине другой истории) в качестве родительского элемента текущего начального коммита, чтобы вставить другую историю за текущей историей:
git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' HEAD
(если родительская строка пуста - что происходит, когда мы имеем дело с начальным коммитом - добавьте graftcommit в качестве родителя).
Это именно то, что я хочу, т.е. установить родителя (для фиксации A
) некоторого корневого коммита (B
). Смотрите здесь для связанных вопросов.
Но что именно является трансплантатом в этой команде? Это новый родитель, т.е. A
?
Далее приведен еще более простой пример для достижения того же:
или даже проще:
echo "$commit-id $graft-id" >> .git/info/grafts git filter-branch $graft-id..HEAD
Опять же, что это $graft-id
должен быть в этом примере? А также $commit-id
знак равно A
, право? Либо это $commit-id
знак равно B
а также $graft-id
знак равно A
?
Я также читал это, но я все еще не понимаю, зачем мне здесь такая концепция. Почему я не могу просто сделать git filter-branch A..HEAD
или так?
Ладно, думаю, я все понял, смотри мой собственный ответ.
Чтобы объяснить, зачем мне это было нужно:
В нашем проекте OpenLieroX в один момент был включен Google Breakpad.
Мы взяли его не из официального SVN (потому что он не работал в то время для меня), а из последней стабильной версии LastFM (это было просто случайно, что было оттуда - у меня это тоже было на моем диске и знал, что люди LastFM, вероятно, взяли какую-то стабильную версию Breakpad).
Затем, когда прошло время, мы применили несколько патчей к нашей собственной копии Google Breakpad.
Теперь, спустя много месяцев, мы хотим немного очистить историю, получить хороший обзор всех наших патчей для Breakpad и, возможно, также вывести их вверх по течению. И самое главное (для нас), мы хотим обновить нашу копию Breakpad.
Итак, я подумал, что лучше всего было бы создать новый репозиторий Git, извлечь откуда-нибудь из него официальную историю исходных текстов и получить всю информацию о Breakpad из нашего основного репозитория через git filter-branch
внутрь. Я использовал это зеркало Breakpad в качестве основы. filter-branch
было также немного сложнее, потому что мы переместили весь каталог Breakpad в одну точку внутри репозитория OpenLieroX.
В итоге я получил три ветки:
breakpad-in-mainsrc
:git filter-branch
в первый раз за время, когда Breakpad был вsrc/breakpad/external
,breakpad-in-libs
:git filter-branch
второй запуск в то время, когда Breakpad был вlibs/breakpad
,official
: Копияmaster
с зеркала Breakpad.
Затем я искал коммит в official
который был наиболее близок к корню в breakpad-in-mainsrc
, У меня не было идеального соответствия, поэтому я использовал самый близкий (написал небольшой скрипт на Python, чтобы понять это). Этот помечен как olx-closest-initial-breakpad
,
И тогда я хотел объединить эти три истории все вместе. Все прошло хорошо, как описано выше (и мой собственный ответ ниже).
Результат здесь: OpenLieroX Google Breakpad на GitHub
2 ответа
Это довольно неясная особенность.
Если вам это нужно, вам лучше вдвойне убедиться, что вы точно знаете, как git работает за кулисами, и знаете, чего вы хотели достичь.
Кроме того, есть более новая, возможно, более полезная (по крайней мере, более гибкая) функция, называемая git replace
( справочная страница)
ИМХО, эта же документация содержит достаточно информации, если вам это действительно нужно.
Но смотри
Хорошо, похоже, работает так, как я ожидал. Чтобы ответить на мои собственные вопросы:
- graft-id - это не что иное, как идентификатор фиксации, то есть SHA1 фиксации.
$commit-id
знак равноB
(хотя это должен быть SHA1, без тегов или около того)$graft-id
знак равноA
(опять же, должен быть SHA1)
Тогда данный еще более простой способ работает, как и ожидалось.