Насколько я знаю, все распределенные системы контроля версий требуют, чтобы вы клонировали весь репозиторий. По этой причине не разумно вкладывать огромное количество контента в один репозиторий (спасибо за этот ответ). Я знаю, что это не ошибка, а функция, но я задаюсь вопросом, является ли это требованием для всех распределенных систем контроля версий.
В распределенных rcs история файла (или фрагмента содержимого) является направленным ациклическим графом, поэтому почему вы не можете просто клонировать эту одну DAG вместо набора всех графиков в репозитории? Возможно, я что-то пропустил, но следующие прецеденты трудно сделать:
Если я повторно использую код других людей из нескольких проектов, я не могу сохранить их полную историю. По крайней мере, в git я могу думать о (довольно сложном) обходном пути:
Я не знаю, возможно ли это также с Mercurial или Bazaar, но по крайней мере это нелегко. Так есть ли распределенная rcs, которая поддерживает частичный checkout/clone по дизайну? Он должен поддерживать одну простую команду, чтобы получить один файл с его историей из одного репозитория и объединить его в другой. Таким образом, вам не нужно будет думать о том, как структурировать ваш контент в репозитории и подмодули, но вы могли бы с радостью разделить и объединить репозитории по мере необходимости (крайний был бы одним репозиторием для каждого отдельного файла).
Ответ 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
)
.
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
)
.
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
)
.
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
)
.
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
)
.
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
)
.
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
)
.
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-кодирование отдельных фильтров.