Git: что такое graftcommit или graft-id?

В git-filter-branch говорится:

Чтобы установить фиксацию (которая обычно находится на вершине другой истории) как родительскую для текущей начальной фиксации, чтобы вставить другую историю за текущей историей:

git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' HEAD

(если родительская строка пуста - что происходит, когда мы имеем дело с начальным коммитом - добавьте graftcommit в качестве родительского).

Это именно то, что я хочу, т.е. установить родителя (для фиксации A) некоторого корневого коммита (B). См. Соответствующий вопрос здесь.

Но что именно означает graft-id в этой команде? Это новый родитель, т.е. 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


person Albert    schedule 22.05.2011    source источник
comment
Вы уверены, что хотите переписать историю? Это означает, что если вы обнаружите ошибку, связанную с breakpad, и захотите понять, когда она появилась, это может оказаться невозможным, поскольку исходный код, который вы отправили, исчез.   -  person Elazar Leibovich    schedule 13.06.2011


Ответы (2)


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

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

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

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

Но смотри

  1. https://git.wiki.kernel.org/index.php/GraftPoint
  2. Для чего нужны .git / info / grafts?
  3. http://bugsquash.blogspot.com/2010/03/stitching-git-histories.html
person sehe    schedule 22.05.2011
comment
Да, я понимаю, как работает Git. Это работает точно так, как ожидалось. Смотрите мой собственный ответ. Я добавил объяснение, зачем мне это нужно. - person Albert; 22.05.2011

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

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

Тогда данный еще более простой способ работает должным образом.

person Albert    schedule 22.05.2011
comment
Если вы сами отвечаете на этот вопрос, возможно, имеет смысл поделиться некоторыми своими знаниями и объяснить, что вы делаете. Есть ряд предостережений, связанных с переписыванием истории и точками прививки, в частности (вы не можете отменить фильтрацию ветки, чтобы сделать прививки постоянными) - person sehe; 22.05.2011
comment
@sehe: Я расширил свой вопрос, добавив некоторую справочную информацию. - person Albert; 22.05.2011