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

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

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

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

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

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

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

Ответы

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

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

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

См. commit 3aa6694, commit aa57b87, commit 35a7ae9, commit 1e1e39b, commit acb0c57, commit bc2d0c3, зафиксировать 640d8b7, зафиксировать 10ac85c (08 декабря 2017 г.), автор Джефф Хостетлер (jeffhostetler).
. См.commit a1c6d7c ,commit c0c578b ,commit 548719f ,commit a174334 , commit 0b6069f (08 декабря 2017 г.) Джонатан Тан (jhowtan)
.

(Merged by Junio C Hamano -- [TG42] -- in commit 6bed209, 13 Feb 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)
.

(Merged by Junio C Hamano -- [TG48] -- in commit 92e1bbc, 28 Jun 2018)

upload-pack: отключить фильтрацию объектов при отключении с помощью конфигурации

Когда 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)
.

(Merged by Junio C Hamano -- [TG416] -- in commit a1e9dff, 19 Oct 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()


чтобы также непосредственно проверять наличие всех объектов для извлечения. Вы можете перечислить объекты частичного клона, за исключением объектов "промисор", с помощью

git rev-list --exclude-promisor-objects
(Только для внутреннего использования.) Предварительный фильтр объекта на границе промисора. Это используется с частичным клоном
.

Это сильнее, чем --missing=allow-promisor, потому что оно ограничивает обход, а не просто заставляет замолчать ошибки об отсутствующих объектах.

Но обязательно используйте Git 2.21 (Q1 2019), чтобы избежать сегфолта. См. коммит 4cf6786 (05 декабря 2018 г.) от Мэтью Девора (matvore)
.

(Merged by Junio C Hamano -- [TG426] -- in commit c333fe7, 14 Jan 2019)

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

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


Запретите разыменование указателя NULL в этой ситуации.

Обратите внимание, что Git 2.21 (Q1 2019) исправляет ошибку: См. коммит bbcde41 (03 декабря 2018 г.) от Мэтью Девора (matvore)
.

(Merged by Junio C Hamano -- [TG435] -- in commit 6e5be1f, 14 Jan 2019)

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

Это приводит к сбою ошибки:

$ 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" в ленивом клоне, мы можем заранее знать, какие недостающие капли нам понадобятся, вместо того, чтобы ждать по требованию механизм, чтобы обнаружить их один за другим.

Цель - повысить производительность, запросив эти обещанные большие двоичные объекты. Смотрите коммит 7fbbcb2 (05 апреля 2019 г.) и коммит 0f4a4fb (29 марта 2019 г.) от Джонатана Тана (jhowtan)
.

. (Merged by Junio C Hamano -- [TG450] -- in commit 32dc15d, 25 Apr 2019)

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

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


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

Git 2.23 (3-й квартал 2019 г.) будет защищен от ошибок в этой партии. См. коммит 31f5256 (28 мая 2019 г.) от Деррика Столи (derrickstolee)
.

(Merged by Junio C Hamano -- [TG456] -- in commit 5d5c46b, 17 Jun 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)
.

(Merged by Junio C Hamano -- [TG476] -- in commit 8867aa8, 21 Jun 2019)

index-pack: предварительная выборка отсутствует REF_DELTA баз
При получении клиент отправляет "have" идентификаторы фиксации, указывающие, что серверу не нужно отправлять какие-либо объекты, на которые ссылаются эти коммиты, сокращение сетевого ввода-вывода.

Когда клиент является частичным клоном, он по-прежнему отправляет "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 разрешить их.


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

Git 2.24 (Q4 2019) исправляет выборку объектов по требованию в ленивом клоне, который неправильно пытался извлечь коммиты из проектов подмодулей, все еще работая в суперпроекте. См. коммит a63694f (20 августа 2019 г.) от Джонатана Тана (jhowtan)
.

(Merged by Junio C Hamano -- [TG493] -- in commit d8b1ce7, 09 Sep 2019)

diff: пропустить GITLINK, когда ленивое извлечение отсутствующих объектов В 7fbbcb2
("diff: пакетное извлечение отсутствующих BLOB-объектов", 2019-04-08, Git v2.22.0-rc0), diff обучали пакетному извлечению отсутствующих объектов при работе с частичный клон, но его не учили воздерживаться от получения GITLINKs.


Научите diff проверять, является ли объект GITLINK, прежде чем включать его в набор для выборки. В Git 2.24 (Q4 2019) также вводится понятие удаленного хранилища promisor

. См.commit 4ca9474 ,commit 60b7a92 ,commit db27dca ,commit 75de085 ,commit 7e154ba ,commit 9a4c507 , коммит 5e46139 , коммит fa3d1b6 , коммит b14ed5a , коммит faf2abf , коммит 9cfebc1 , коммит 9e27bea , коммит 48de315 , коммит 2e86067 , коммит c59c7c8 (25 июня 2019 г.) от Кристиана Кудера (chriscool )
.

(Merged by Junio C Hamano -- [TG4100] -- in commit b9ac6c5, 18 Sep 2019) partial-clone документация определяет промо-репо как:

Удаленный, который позже может предоставить отсутствующие объекты, называется Promisor Remote, так как он обещает отправить объекты, когда просил.

Изначально Git поддерживал только один удаленный промисор, происхождение удаленный, с которого пользователь клонировал и который был настроен в Параметр конфигурации [extensions.partialClone.
Позже была реализована поддержка нескольких пультов Promisor.

Многие пульты Promisor можно настроить и использовать.

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

Пульты дистанционного управления, которые считаются "promisor" удаленными, указаны следующие переменные конфигурации:

  • extensions.partialClone = <name>
  • remote.<name>.promisor = true
  • remote.<name>.partialCloneFilter = ...

Только один пульт дистанционного управления Promisor можно настроить с помощью переменной конфигурации extensions.partialClone. Этот пульт дистанционного управления Promisor будет последним, который пытался получить объекты.


Git 2.24 (Q4 2019) также улучшает понятие фильтров в частичном клоне.

Смотрите коммит 90d21f9, коммит 5a133e8, коммит 489fc9e, коммит c269495, коммит cf9ceb5, коммит f56f764, коммит e987df5, коммит 842b005, коммит 7a7c7f4, коммит 9430147 (27 июня 2019 г.) от Мэтью Девор (matvore).
(Merged by Junio C Hamano -- [TG4110] -- in commit 627b826, 18 Sep 2019)

Это позволяет:

  • объединение фильтров таким образом, что отображаются только объекты, принятые всеми фильтрами.
    Мотивация для этого состоит в том, чтобы позволить получать списки каталогов, не выбирая также BLOB-объектов. Это можно сделать, комбинируя blob:none с tree:<depth>.
    Существуют массивные репозитории, которые имеют деревья больше, чем ожидалось, даже если вы включаете только один коммит.

Комбинированный фильтр поддерживает любое количество подфильтров и записывается в следующая форма:

combine:<filter 1>+<filter 2>+<filter 3>
  • объединение нескольких фильтров простым повторением флага --filter.
    Раньше пользователю приходилось неловко объединять их в один флаг (например, --filter=combine:FOO+BAR), включая URL-кодирование отдельных фильтров.

Ответ 5

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

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

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

Там есть запланированная функция Вложенные деревья для базара, что, возможно, позволит частично проверить.

Ответ 6

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

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

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

Ответ 7

От 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.

Это что-то вроде того, что вы ищете?