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

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

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

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

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

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

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

7 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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


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

Смотрите коммит cac1137 (11 июня 2018 г.) Джонатана Тана ( jhowtan )
(Объединено Юнио С Хамано - 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 msgstr "в частичном клоне не удалось правильно получить запрашиваемый объект, на который ссылается объект в файле пакета promisor, который был исправлен.

См. Коммит 35f9e3e, коммит 4937291 (21 сентября 2018 г.) Джонатана Тана ( jhowtan )
(Объединено Юнио С Хамано - gitster - в комитете 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() также непосредственно проверять наличие всех объектов, которые будут выбраны.

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

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам