Для чего нужны .git/info/grafts?

Я пытаюсь выяснить, что такое "трансплантаты" в Git.

Например, в одном из последних комментариев здесь, Тобу предположим использовать git -фильтр-ветвь и .git/info/grafts, чтобы присоединиться к двум репозиториям.

Но я не понимаю, зачем мне эти прививки? Кажется, что все работают без двух последних команд.

Ответ 1

Из Git Wiki:

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

Причины использования трансплантатов

Прививки могут быть полезны при перемещении до git, поскольку он позволяет вы делаете клонирование старой истории импортированный из другого SCM. Это сохраняет начальный клон для пользователей кто просто хочет следовать последним версии, пока разработчики могут полная история развития доступны.

Когда Linus начал использовать git для поддерживая свое дерево ядра не было никаких инструментов для преобразования старой истории ядра. Позже, когда старая история ядра была импортирована в git из шлюза bkcvs, графты были созданный как способ его создания можно связать два разных репозитории вместе.

Ответ 2

При работе с git -svn:

git графты очень полезны для импорта дерева Git в репозиторий Subversion.

например. Я создал локальный репозиторий Git как начало. После работы над ним несколько дней, создав множество коммитов, мне пришлось опубликовать его в центральном репозитории Subversion, и я не хотел потерять историю.

Я нашел следующую практическую статью: http://eikke.com/importing-a-git-tree-into-a-subversion-repository/

Ответ 3

Подход трансплантатов , упомянутый Крисом Джонсеном для объединения двух репозиториев, больше не является полностью действительным (только с трансплантатами).
В Git 2.18 (Q2 2018) функциональность "$GIT_DIR/info/grafts" была заменена механизмом "refs/replace/" (в течение некоторого времени).
Внутренний код имел поддержку для этого во многих местах, который был очищен для того, чтобы сбросить опору механизма "трансплантатов".

См. commit a3694d9, commit f42fa47, commit 8d0d81a, commit e2d65c1, commit f9f99b3, commit 0115e03, коммит fb40429, коммит 041c98e, коммит e24e871 (28 апреля 2018 года) и коммит d398f2e, коммит fef461e, коммит c5aa6db (25 апреля 2018 г.) от Йоханнеса Шинделина (dscho).
(Merged by Junio C Hamano -- [TG43] -- in commit 352cf6c, 23 May 2018)

Так что вместо

echo "$commit-id $graft-id" >> .git/info/grafts

Теперь вы делаете:

git replace --graft $commit-id $graft-id
git filter-branch $graft-id..HEAD

Устаревшая поддержка .git/info/grafts

Функция прививки была удобным способом "сшить" древние история к новому началу linux.git.

Однако его реализация не соответствует стандартам Git, так как слишком много способов, где это может привести к неожиданному и нежелательному поведению.

Например, при выталкивании из хранилища с активными трансплантатами это можно пропустить коммиты, которые были "привиты", в результате чего нарушенное состояние на другой стороне.

Кроме того, функция прививки ограничена списком комитетов родители, это не может заменить ничего другого.

Гораздо более молодая функция, реализованная как git replace, предназначена для исправления эти ограничения и опасные ошибки.

Видя, что git replace уже достаточно зрел (поскольку 4228e8b(замените: добавьте опцию --graft, 2014-07-19, Git 2.1.0) он может выполнить прививку обязанности файла), пришло время отказаться от поддержки файла трансплантата, и в конце концов уйти в отставку.

Теперь (снова Git 2.18, Q2 2018) у вас есть:

replace: добавить опцию --graft

Строка использования для этой опции:

git replace [-f] --graft <commit> [<parent>...]

Сначала мы создаем новый коммит, который совпадает с <commit> за исключением того, что его родители [<parents>...]

Затем мы создаем ref ref, который заменяется на коммит, который мы только что создали.

С этой новой опцией, это должно быть просто конвертировать трансплантаты для замены ссылок


И до Git 2.20 (Q4 2018) недавно введенные вспомогательные данные графа коммитов несовместимы с такими механизмами, как replace & трансплантаты, которые "нарушают" неизменную природу объектных отношений.
Отключите оптимизации, основанные на их использовании (и обновите существующий коммит-граф), когда эти несовместимые функции используются в хранилище.

См. commit 829a321, commit 5cef295, commit 20fd6d5, commit d653824, commit b775896, commit 950c62b (20 Aug 2018) by (20 августа 2018 г.) Деррик Столи (derrickstolee).
См. commit 212e0f7, commit 4a6067c (20 августа 2018) от Стефан Беллер (stefanbeller).
(Merged by Junio C Hamano -- [TG418] -- in commit 6d8f8eb, 16 Oct 2018)


В Git 2.24 (Q4 2019) "upload-pack" (аналог "git fetch"), которому необходимо отключить коммит-граф при ответе на мелкий запрос клонирования/выборки, больше не паникует.

См. коммит 6abada1, коммит fbab552 (12 сентября 2019 г.) от Джеффа Кинга (peff).
(Merged by Junio C Hamano -- [TG422] -- in commit 098e8c6, 07 Oct 2019)

## upload-pack: более аккуратно отключить граф коммитов для мелкого обхода

Когда клиент запрашивает определенные мелкие опции, такие как "deepen-Since", мы выполняем пользовательский обход списка ревью, который притворяется мелким.
Прежде чем сделать это, мы должны отключить коммит-граф, поскольку он не совместим с поверхностным представлением хранилища. Это обрабатывается 829a321 (commit-graph: close_commit_graph перед мелкой прогулкой, 2018-08-20, Git v2.19.2).
Этот коммит буквально закрывает и освобождает наш repo->objects->commit_graph struct.

Это создает интересную проблему для коммитов, которые уже были анализируется с использованием графика коммитов.
Их флаг commit->object.parsed установлен, их commit->graph_pos установлен, но их commit->maybe_tree все еще может быть NULL.
Когда кто-то позже вызывает repo_get_commit_tree(), мы видим, что мы еще не загрузили oid дерева и пытаемся получить его из графа фиксации.
Но так как это было освобождено, мы segfault!

Таким образом, корень проблемы заключается в зависимости данных между коммитом Ленивая загрузка дерева OID и тот факт, что граф фиксации может пойти в середине процесса.