Есть ли распределенная система контроля версий, которая поддерживает частичную проверку / клонирование? - PullRequest
15 голосов
/ 23 июня 2010

Насколько мне известно, все распределенные системы контроля версий требуют клонирования всего хранилища.По этой причине не стоит помещать огромное количество контента в один репозиторий (спасибо за этот ответ ).Я знаю, что это не ошибка, а функция, но мне интересно, является ли это требованием для всех распределенных систем контроля версий.

В распределенных rcs история файла (или части содержимого) являетсянаправленный ациклический граф, так почему же вы не можете просто клонировать этот единственный DAG вместо набора всех графов в хранилище?Может быть, я что-то упускаю, но трудно сделать следующие варианты использования:

  • клонировать только часть репозитория
  • объединить два репозитория (сохраняя их историю!)
  • копировать некоторые файлы с их историей из одного хранилища в другое

Если я повторно использую части кода других людей из нескольких проектов, я не могу сохранить их полную историю.По крайней мере, в git я могу придумать (довольно сложный) обходной путь:

  1. клонировать полный репозиторий
  2. удалить все содержимое, которое меня не интересует
  3. переписатьистория удаления всего, что отсутствует в мастере
  4. , объединить оставшийся репозиторий в существующий репозиторий

Я не знаю, возможно ли это также с Mercurial или Bazaar, но впо крайней мере, это совсем не просто.Так есть ли какие-либо распределенные rcs, которые поддерживают частичную проверку / клонирование по дизайну?Он должен поддерживать одну простую команду, чтобы получить один файл с его историей из одного репозитория и объединить его в другой.Таким образом, вам не нужно думать о том, как структурировать ваш контент в репозитории и подмодули, но вы можете с легкостью разбивать и объединять репозитории по мере необходимости (в крайнем случае это будет один репозиторий для каждого отдельного файла).

Ответы [ 7 ]

7 голосов
/ 25 июня 2010

Начиная с версии 2.0, невозможно создать так называемый «узкий клон» с Mercurial, то есть клон, в котором вы извлекаете данные только для определенного подкаталога. Мы называем это «мелким клоном», когда вы извлекаете только часть истории, скажем, последние 100 ревизий.

Как вы говорите, в общей модели истории на основе DAG нет ничего, что исключало бы эту функцию, и мы работали над ней. Питер Арренбрехт, участник Mercurial, реализовал два разных подхода для узких клонов, но ни один из них еще не был объединен.

Кстати, вы, конечно, можете разбить существующий репозиторий Mercurial на части, где каждый меньший репозиторий имеет историю только для определенного подкаталога исходного репозитория. Инструмент convert является инструментом для этого. Однако каждое из меньших репозиториев не будет связано с большим репозиторием - самая сложная задача состоит в том, чтобы сделать разделение бесшовным, чтобы наборы изменений сохраняли свои идентичности.

5 голосов
/ 23 июня 2010

В распределенных rcs история файла (или части содержимого) представляет собой ориентированный ациклический граф, так почему бы просто не клонировать этот единственный DAG вместо набора всех графов в репозитории?

По крайней мере, в Git группа обеспечения доступности баз данных, представляющая историю репозитория, применяется к репозиторию whole , а не к одному файлу. Каждый объект фиксации указывает на объект «дерево», который представляет все состояние хранилища в то время.

Git 1.7 поддерживает «редкие проверки» , которые позволяют вам ограничивать размер вашей рабочей копии. Однако все данные хранилища все еще клонируются.

5 голосов
/ 23 июня 2010

Существует модуль поддерева для git, позволяющий вам разделить часть репозитория на новое хранилище, а затем объединить изменения в / из оригинала и поддерева. Вот его readme на github: http://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt

3 голосов
/ 18 февраля 2018

Начиная с Git 2.17 (Q2 2018, 10 лет спустя), будет возможным сделать то, что планировал внедрить Mercurial: " узкий клон ", то есть клон, в котором вы извлекаете данные только для определенного подкаталога.
Это также называется «частичным клоном».

Это отличается от текущего

  • мелкий клон
  • копия того, что вам нужно, из клонированного репозитория в другую рабочую папку.

См. commit 3aa6694 , commit aa57b87 , commit 35a7ae9 , commit 1e1e39b , commit acb0c57 , commit bc2d0c3 , commit 640d8b7 , commit 10ac85c (08.12.2017) от Джефф Хостетлер (jeffhostetler) .
См. commit a1c6d7c , commit c0c578b , commit 548719f , commit a174334 , commit 0b6069f (08 дек 2017) Джонатан Тан (jhowtan) .
(Объединено с Junio ​​C Hamano - gitster - в коммит 6bed209 , 13 февраля 2018 г.)

Вот тесты для частичного клона :

git clone --no-checkout --filter=blob:none "file://$(pwd)/srv.bare" pc1 

Есть другие другие коммиты, вовлеченные в реализацию узкого / частичного клона .

В частности, commit 8b4c010 :

sha1_file: поддержка ленивой выборки отсутствующих объектов

Научить sha1_file извлекать объекты с пульта, настроенного в extensions.partialclone всякий раз, когда объект запрашивается, но отсутствует.


Предупреждение относительно Git 2.17 / 2.18: недавнее добавление экспериментальной функции "частичное клонирование" появилось, когда этого не следует делать, а именно, когда не определен фильтр частичного клонирования, даже если установлен extensions.partialclone.

См. коммит cac1137 (11 июня 2018 г.) от Джонатана Тана (jhowtan) .
(Объединено с Junio ​​C Hamano - gitster - в коммит 92e1bbc , 28 июня 2018 г.)

upload-pack: отключить фильтрацию объектов при отключении через config

Когда upload-pack получил частичную поддержку клонирования (v2.17.0-rc0 ~ 132 ^ 2 ~ 12, 2017-12-08), он был защищен элементом конфигурации uploadpack.allowFilter чтобы позволить операторам серверов контролировать, когда они начнут поддерживать его.

Этот элемент конфигурации не зашел достаточно далеко: он контролирует, Объявляется возможность 'filter', но если (пользовательский) клиент игнорирует объявление о возможностях и пропуск спецификации фильтра в любом случае, сервер справится с этим, несмотря на то, что allowFilter имеет значение false.

Это особенно важно, если в системе безопасности обнаружена ошибка этот новый экспериментальный частичный код клона.
Установки без uploadpack.allowFilter не должны быть затронуты, так как они не намерены поддерживать частичное клонирование, но они будут сметены уязвима.


Это улучшено в Git 2.20 (Q2 2018), так как "git fetch $repo $object" в частичном клоне не правильно выбрал запрашиваемый объект, на который ссылается объект в файле пакета promisor, который был исправлен.

См. коммит 35f9e3e , коммит 4937291 (21 сентября 2018) Джонатан Тан (jhowtan) .
(Объединено с Junio ​​C Hamano - gitster - в commit a1e9dff , 19 октября 2018 г.)

fetch: при частичном клонировании проверить наличие целей

При извлечении объекта, который известен как объект промисора, в локальный хранилище, проверка подключения в quickfetch() в builtin/fetch.c завершается успешно, в результате чего перенос объекта обходит.
Однако этого не должно произойти, если этот объект просто обещан, а на самом деле не присутствует.

Потому что это происходит, когда пользователь вызывает "git fetch origin <sha-1>" на командная строка, объект <sha-1> не может быть выбран даже хотя команда возвращает код завершения 0. Это аналогичная проблема (но с другой причиной) по сравнению с a0c9016 («upload-pack: отправка объектов refs несмотря на« filter »», 2018-07-09, Git v2.19.0-rc0).

Поэтому обновите quickfetch(), чтобы также непосредственно проверить наличие всех объектов для извлечения.


Вы можете перечислить объекты частичного клона, исключая объекты "promisor", с помощью git rev-list --exclude-promisor-objects

(Только для внутреннего использования.) Предварительный фильтр объекта на границе промисора.
Используется с частичным клоном .
Это сильнее, чем --missing=allow-promisor, потому что оно ограничивает обход, а не просто заставляет замолчать ошибки об отсутствующих объектах.

Но обязательно используйте Git 2.21 (Q1 2019), чтобы избежать ошибки segfault.

См. коммит 4cf6786 (05 декабря 2018) Мэтью Девор (matvore) .
(Объединено с Junio ​​C Hamano - gitster - в коммит c333fe7 , 14 января 2019 г.)

"git rev-list --exclude-promisor-objects" должен был взять объект, который не существует локально (и лениво доступен), из командной строки без рывков, но код разыменовал NULL.

list-objects.c: не создавать ошибки для отсутствующих объектов cmdline

Когда команда вызывается как с --exclude-promisor-objects, --objects-edge-aggressive, так и с отсутствующим объектом в командной строке, массив rev_info.cmdline может получить нулевой указатель на значение поля 'item'.
Не допускайте разыменования указателя NULL в этой ситуации.


Обратите внимание, что Git 2.21 (Q1 2019) исправляет ошибку:

См. коммит bbcde41 (3 декабря 2018 г.) от Мэтью Деворе (matvore) .
(Объединено Junio ​​C Hamano - gitster - в коммит 6e5be1f , 14 января 2019 г.)

exclude-promisor-objects: объявить, когда опция разрешена

Опция --exclude-promisor-objects вызывает странное поведение в минимум две команды: log и blame.
Вызывает ошибку BUG:

$ git log --exclude-promisor-objects
BUG: revision.c:2143: exclude_promisor_objects can only be used
when fetch_if_missing is 0
Aborted
[134]

Исправьте это так, чтобы параметр обрабатывался как любой другой неизвестный параметр.
Команды, которые должны его поддерживать, ограничены, поэтому объявляйте в этих командах, что флаг поддерживается.
В частности:

pack-objects
prune
rev-list

Команды были найдены путем поиска логики, которая анализирует --exclude-promisor-objects вне revision.c.
Необходима дополнительная логика вне revision.c, потому что fetch_if_missing должен быть включен до того, как revision.c увидит опцию, иначе произойдет сбой BUG. Приведенный выше список подтверждается тем фактом, что никакая другая команда не вызывается интроспективно другой командой, передающей --exclude-promisor-object.


Git 2.22 (Q2 2019) оптимизирует узкий клон:
Запустив "git diff" в ленивом клоне, мы можем заранее знать, какие недостающие капли нам понадобятся, вместо того, чтобы ждать по требованию машины, чтобы обнаружить их один за другим.
Цель - повысить производительность, запросив эти обещанные BLOB-объекты.

См. коммит 7fbbcb2 (05 апреля 2019 г.) и коммит 0f4a4fb (29 марта 2019 г.) Джонатан Тан (jhowtan) .
(Объединено с Junio ​​C Hamano - gitster - в коммит 32dc15d , 25 апреля 2019 г.)

diff: пакетное извлечение отсутствующих BLOB-объектов

При выполнении команды типа "git show" или "git diff" в частичном клоне, Пакет всех отсутствующих BLOB-объектов, которые будут получены как один запрос.

Это похоже на c0c578b ("unpack-trees: пакетная загрузка отсутствует blobs ", 2017-12-08, Git v2.17.0-rc0), но для другой команды.


Git 2.23 (Q3 2019) будет защищать будущее от той партии, в которой отсутствует BLOB-часть.

См. коммит 31f5256 (28 мая 2019 г.) от Деррик Столи (derrickstolee) .
(Объединено Junio ​​C Hamano - gitster - в коммит 5d5c46b , 17 июня 2019 г.)

sha1-file: сплит OBJECT_INFO_FOR_PREFETCH

Битовый флаг OBJECT_INFO_FOR_PREFETCH был добавлен к sha1-file.c в 0f4a4fb (sha1-file: поддержка OBJECT_INFO_FOR_PREFETCH, 2019-03-29, Git v2.22.0-rc0) и используется для предотвращения fetch_objects() метод при включении.

Однако существует проблема с текущим использованием.
Определение OBJECT_INFO_FOR_PREFETCH дается путем добавления 32 к OBJECT_INFO_QUICK.
Это четко указано выше определения (в комментарии), что это так OBJECT_INFO_FOR_PREFETCH подразумевает OBJECT_INFO_QUICK.
Проблема в том, что использование «flag & OBJECT_INFO_FOR_PREFETCH» означает, что OBJECT_INFO_QUICK также подразумевает OBJECT_INFO_FOR_PREFETCH.

Разделить один бит из OBJECT_INFO_FOR_PREFETCH на новый OBJECT_INFO_SKIP_FETCH_OBJECT как один бит и сохранить OBJECT_INFO_FOR_PREFETCH как союз двух флагов.

И "git fetch" в ленивого клона забыли выбрать базовые объекты, которые необходимо заполнить дельту в тонком пакете, который был исправлено.

См. коммит 810e193 , коммит 5718c53 (11 июня 2019 г.) и коммит 8a30a1e , коммит 385d1bf (14 мая 2019 г.) Джонатан Тан (jhowtan) .
(Объединено Junio ​​C Hamano - gitster - в коммит 8867aa8 , 21 июня 2019 г.)

index-pack: предварительная выборка отсутствует REF_DELTA базы

При получении клиент отправляет "1372 *" идентификаторы фиксации, указывающие, что серверу не нужно отправлять какие-либо объекты, на которые ссылаются эти коммиты, сокращение сетевого ввода-вывода.
Когда клиент является частичным клоном, клиент по-прежнему отправляет «have» таким образом, даже если у него нет каждого объекта, на который ссылается коммит, отправленный как «have».

Если сервер пропускает такой объект, это нормально: клиент может лениво получить этот объект до этой выборки, и он все еще может сделать это после.

Проблема заключается в том, что сервер отправляет тонкий пакет, содержащий объект, REF_DELTA против такого отсутствующего объекта: index-pack не удается исправить тонкий пакет.
Когда в 8b4c010 была добавлена ​​поддержка отложенной выборки отсутствующих объектов («sha1_file: поддержка отложенной выборки отсутствующих объектов», 2017-12-08, Git v2.17.0-rc0), поддержка в index-pack была отключено из-за убеждения, что он обращается к репо только для проверки хеш-коллизий.
Тем не менее, это не так: он также должен получить доступ к репо, чтобы решить REF_DELTA основ.

Поддержка отложенной выборки обычно должна быть отключена в index-pack, поскольку она используется как часть самого процесса отложенной выборки (в противном случае могут возникать бесконечные циклы), но нам нужно извлечь базы REF_DELTA .
(При извлечении REF_DELTA баз маловероятно, что они сами REF_DELTA, потому что мы не отправляем "have" при выполнении таких выборок.)

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

3 голосов
/ 01 августа 2010

Я надеюсь, что один из этих RCS добавит возможность узкого клонирования.Насколько я понимаю, архитектура GIT (изменения / перемещения, отслеживаемые по всему репо) делает это очень трудным.

Bazaar гордится поддержкой множества различных типов рабочих процессов.Отсутствие возможности узкого клонирования запрещает SVN / CVS-подобный рабочий процесс в bzr / hg / git, поэтому я надеюсь, что они будут мотивированы, чтобы найти какой-то способ сделать это.

Новые функции не должны появиться вза счет базовых функций, таких как возможность извлечения одного файла / каталога из репозитория.«Распределенная» функция современных rcs - это «круто», но, на мой взгляд, не одобряет хорошие практики разработки (частые слияния / непрерывная интеграция).Кажется, что все эти новые RCS не имеют базовой функциональности.Даже SVN без реальной поддержки ветвления / пометки казался шагом назад по сравнению с CVS imo.

3 голосов
/ 23 июня 2010

На базаре вы можете разделять и объединять части хранилища.

Команда split позволяет разделить хранилище на несколько хранилищ. Команда join позволяет объединять репозитории. Оба хранят историю.

Однако это не так удобно для SVN-модели, где вы можете оформить / зафиксировать поддерево.

Существует запланированная функция Nested-Trees для базара, которая может позволить частичные проверки.

0 голосов
/ 03 ноября 2012

С git help clone:

--depth <depth> Create a shallow clone with a history truncated to the specified number of revisions. A shallow repository has a number of limitations (you cannot clone or fetch from it, nor push from nor into it), but is adequate if you are only interested in the recent history of a large project with a long history, and would want to send in fixes as patches.

Это обеспечивает что-то вроде того, что вы ищете?

...