Git: что такое graftcommit или идентификатор трансплантата?

В 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 -second-run за время, когда Breakpad находился в libs/breakpad.
  • official: Копировать master из Зеркало брейк-панели.

Затем я искал фиксацию в official, которая была ближе всего к корню в breakpad-in-mainsrc. У меня не было идеального соответствия, поэтому я использовал самую близкую (написал небольшой Python script, чтобы понять это). Теперь он помечен как olx-closest-initial-breakpad.

И тогда я хотел объединить эти три истории вместе. Это прошло отлично, как описано выше (и, учитывая мой собственный ответ ниже).

Результат здесь: OpenLieroX Google Breakpad на GitHub

Ответ 1

Это довольно неясная особенность.

Если вам это нужно, вы должны быть уверены, что знаете точно, как git работает за кулисами, и вы знаете, чего именно вы хотели достичь.

Кроме того, существует более новая, возможно более полезная (по крайней мере, более гибкая) функция, называемая git replace (справочная страница)

ИМХО, эта же документация содержит достаточную информацию, если вам это действительно нужно.

Но см.

Ответ 2

Хорошо, похоже, работает так, как я ожидал. Чтобы ответить на мои вопросы:

  • graft-id - это не что иное, как commit-id, то есть SHA1 коммита.
  • $commit-id= B (это должен быть SHA1, хотя и не теги).
  • $graft-id= A (опять же, должен быть SHA1)

Тогда данный еще более простой способ работает так, как ожидалось.