On Tue, Sep 26, 2006 at 02:14:25PM +0400, Alex V. Myltsev wrote: > У меня есть такое представление о том, как должен работать gear-release: > > * Читает .gear-tags, в котором написано: > branch1 path1 > branch2 path2 branch1 - это имя, которое gear-release в момент запуска преобразует в sha1? В таком случае, даже если .gear-tags лежит в репозитории, это само по себе ничего не значит, так как неизвестно, на что указывала ссылка с указанным именем в момент запуска gear-release, следовательно, действия мантейнера невозможно повторить (разве что попытаться найти, куда показывала ссылка, по совпадению tree id, но в этом случае однозначный результат не гарантируется)... > ... > * Из каждого бранча извлекает tree id посредством git-rev-parse и > git-cat-file. > * Создаёт новое дерево следующим путём: > { > git-ls-tree HEAD > for (tree, path) in .gear-tags: > echo "040000 tree $tree $path" > } >git-mktree > То есть пришивает к текущему дереву деревья из нужных бранчей под > нужными именами. ... Разве что модифицировать .gear-tags в этом дереве, добавив туда реально использованные sha1 пришитых бранчей. > * Создаёт новый коммит1, который ссылается на новосозданное дерево, а > родителем числит прошлый release commit. Создаёт новый коммит2, > который ссылается на новосозданное дерево, но не имеет родителей. Откуда берётся прошлый release commit? Придётся заводить для таких коммитов какую-то специальную ветку. У коммит1, если уж делать его в таком виде, нужно вторым родителем ставить текущий коммит, иначе у того, что будет собираться, не будет никакой связи с реальной историей разработки. Впрочем, в gitk это всё равно будет выглядеть отвратительно - либо мегапатч, либо мега-merge. > * Создаёт и подписывает два тэга: release-$version с коммитом1 и > release-$version-bare с коммитом2. > > Теперь > - на новосозданные тэги можно применять gear в неизменённом виде. > - если .gear-tags пуст, то gear можно применять и на HEAD; если > .gear-tags непуст, то gear не найдёт в нём path* и отвалится. > Это напоминание сборщику, что HEAD требует применения gear-release. Это неудобно - как минимум, нужен wrapper, позволяющий вызвать gear одной командой (либо поддержка в самом gear). Вообще предполагалось, что gear-release используется при направлении окончательного релиза на сборку в Сизиф; в данном случае инструмент для сшивания деревьев придётся применять существенно чаще - вероятно, это должен быть не gear-release, а что-то другое. > - наследственность тэгов вида release-$version по-прежнему можно > проверять при входе в Сизиф, если считать, что майнтейнеры честны, > хотя, может быть, забывчивы. (Если майнтейнеры нечестны, то проверка > наследственности не помогает в любом случае.) > - тэги release-*-bare можно использовать, если нужно скачать все > исходники какой-то версии, и только их. Специальной поддержки со > стороны git не требуется. Соответствие $release и $release-bare > проверяется тривиально. От такого release-*-bare пользы примерно столько же, сколько и от git-archive --remote=... - при отсутствии связей между коммитами все объекты всегда передаются полностью (точнее, только с gzip-сжатием каждого объекта отдельно - количеством дельт между объектами одного дерева можно пренебречь). Экспериментальная проверка работы git с несвязанными коммитами на репозитории linux-2.6 показала следующее: - Размер pack-файла bare/v2.6.17 - 58M. - Размер pack-файла bare/v2.6.18 - 59M. Именно столько придётся вытянуть при получении bare/v2.6.18, не связанного с другими коммитами, даже при наличии в локальном репозитории bare/v2.6.17. - Размер pack-файла bare/v2.6.18, из которого исключены объекты, общие с деревом bare/v2.6.17 - 38M. Такой pack-файл придётся получить при выполнении git-fetch -k ... tag bare/v2.6.18-linked (этот тег указывает на коммит с деревом v2.6.18^{tree}, для которого в качестве единственного родительского коммита записан bare/v2.6.17^{commit}). При отсутствии связей между коммитами не удаётся получить даже такой результат. - Размер pack-файла bare/v2.6.18-linked, который сформирован с ключом --thin в предположении о наличии у клиента bare/v2.6.17 - 5,3M. Такой pack передаётся при выполнении git-fetch ... tag bare/v2.6.18-linked без опции -k. Вот так должен работать нормальный fetch с использованием родных протоколов git. Учитывая то, что на основе release-*-bare нельзя продолжать нормальную разработку (разве что чуть подпатчить spec - патчи для остальных компонентов уже не будут накладываться на исходный вариант из-за изменения путей), такой вариант даёт довольно мало преимуществ. Кроме того, имея подобный коммит, никак не связанный с остальной историей, невозможно получить изменения исходников относительно оригинальной версии (разве что в дерево для этого коммита будут помещаться оригинальные исходники и автоматически сформированные патчи).