bundle-uri
Git-бандлы — это файлы, в которых хранится pack-файл вместе с дополнительными метаданными, включая набор ссылок и (возможно, пустой) набор необходимых коммитов. Дополнительные сведения см. в git-bundle[1] и gitformat-bundle[5].
URI бандлов — это адреса, с которых Git может загрузить один или несколько бандлов, чтобы заранее подготовить базу объектов перед получением остальных объектов с удалённого сервера.
Одна из целей — ускорить клонирование и получение данных для пользователей с плохим сетевым соединением с исходным сервером. Ещё одно преимущество — возможность для активных пользователей, например ферм сборки CI, задействовать локальные ресурсы для большей части данных Git и тем самым снизить нагрузку на исходный сервер.
Чтобы включить поддержку URI бандлов, пользователи могут указать URI бандла с помощью параметров командной строки, либо исходный сервер может сообщить один или несколько URI с помощью возможности протокола версии 2.
Цели проектирования
Стандарт URI бандлов призван быть достаточно гибким, чтобы удовлетворять требованиям различных сценариев использования. Поставщик бандлов и клиент Git могут выбирать разные способы создания и использования URI бандлов.
-
Сервер может присваивать бандлам любые имена. Имя может указывать на неизменяемые данные, например содержать хеш содержимого бандла. Однако в этом случае после каждого обновления содержимого потребуется новый URI. Это может быть приемлемо, если URI сообщает сервер (и сервер знает о создании новых бандлов), но будет неудобно для пользователей, указывающих URI с помощью параметра командной строки.
-
Бандлы можно организовать специально для первоначальной подготовки полных клонов, но их также можно организовать для первоначальной подготовки инкрементального получения данных. Поставщик бандлов должен выбрать одну из нескольких схем организации, чтобы минимизировать загрузки клиента при инкрементальном получении данных, однако клиент Git также может выбрать, использовать ли бандлы для любой из этих операций.
-
Поставщик бандлов может поддерживать полное клонирование, частичное клонирование или оба варианта. Клиент может определить, какие бандлы подходят для фильтра частичного клонирования репозитория, если он задан.
-
Поставщик бандлов может использовать один бандл (только для клонирования) или список бандлов. При использовании списка бандлов поставщик может указать, требуется ли клиенту
allURI бандлов для полного клонирования или достаточноanyодного из URI бандлов. Это позволяет поставщику бандлов использовать разные URI для разных географических регионов. -
Поставщик бандлов может организовать бандлы с помощью эвристик, например токенов создания, чтобы клиент мог не загружать ненужные ему бандлы. Если поставщик бандлов не предоставляет такие эвристики, клиент может использовать оптимизации для минимизации объёма загружаемых данных.
-
Поставщик бандлов не обязан быть связан с сервером Git. Клиент может выбрать поставщика бандлов, даже если сервер Git его не рекламирует.
-
Клиент может обнаруживать поставщиков бандлов, рекламируемых сервером Git. Это может происходить во время
gitclone, во времяgitfetch, в обоих случаях или ни в одном из них. Пользователь может выбрать наиболее подходящее сочетание. -
Клиент может в любой момент вручную настроить поставщика бандлов. Клиент также может вручную указать поставщика бандлов в качестве параметра командной строки для
gitclone.
Каждый репозиторий уникален, и потребности у каждого сервера Git разные. Будем надеяться, что поддержка URI бандлов достаточно гибкая, чтобы удовлетворить все потребности. Если это не так, эту возможность можно будет расширить с помощью механизма версионирования.
Требования к серверу
Для реализации серверной части серверов бандлов не требуется изменять другие части протокола Git. Это позволяет сопровождающим серверов использовать решения для статического контента, например CDN, для предоставления файлов бандлов.
В текущих рамках поддержки URI бандлов предполагается, что все URI являются URL HTTP(S), а содержимое загружается по этому URL в локальный файл с помощью запроса GET. Сервер может требовать аутентификацию для таких запросов, чтобы активировать настроенный помощник учётных данных и обеспечить безопасный доступ. (В будущих расширениях могут использоваться URI «file://» или URI SSH.)
Предполагается, что сервер вернул ответ 200 OK; после этого проверяется содержимое URL. Сначала Git пытается разобрать файл как файл бандла версии 2 или более поздней. Если файл не является бандлом, он разбирается как обычный текстовый файл с помощью анализатора конфигурации Git. Предполагается, что пары «ключ-значение» в этом файле конфигурации описывают список URI бандлов. Если обе попытки разбора завершаются неудачей, Git сообщит пользователю об ошибке: URI бандла содержит некорректные данные.
Любые другие данные, предоставленные сервером, считаются некорректными.
Списки бандлов
Сервер Git может сообщать URI бандлов с помощью набора пар key=value. URI бандла также может вести к текстовому файлу в формате конфигурации Git, содержащему те же пары key=value. В обоих случаях это считается bundle list. Пары задают сведения о бандлах, которые клиент может использовать, чтобы решить, какие бандлы загружать, а какие пропустить.
Некоторые ключи описывают свойства самого списка.
- bundle.version
-
(Обязательный) Это значение задаёт номер версии списка бандлов. Если в будущем в Git появится возможность, требующая от клиента Git обрабатывать новый ключ в файле списка бандлов, номер версии будет увеличен. Сейчас существует только версия 1; если указано любое другое значение, Git не будет использовать этот файл.
- bundle.mode
-
(Обязательный) Это значение может быть одним из двух:
allиany. Если указаноall, клиенту следует рассчитывать на необходимость использовать все перечисленные URI бандлов, соответствующие требованиям его репозитория. Если указаноany, клиенту следует рассчитывать, что будет достаточно любого одного URI бандла, соответствующего требованиям его репозитория. Обычно параметрanyиспользуется для перечисления нескольких серверов бандлов, расположенных в разных географических регионах. - bundle.heuristic
-
Если существует этот ключ со строковым значением, список бандлов предназначен для эффективной работы с инкрементальными командами
gitfetch. Эвристика указывает на наличие дополнительных ключей для каждого бандла, которые помогают определить, какое подмножество бандлов следует загрузить клиенту. Единственная запланированная на данный момент эвристика —creationToken.
В оставшихся ключах используется сегмент <id> — имя каждого доступного бандла, заданное сервером. Сегмент <id> должен содержать только буквенно-цифровые символы и символы -.
- bundle.<id>.uri
-
(Обязательный) Это строковое значение задаёт URI для загрузки бандла <id>. Если URI начинается с протокола (
http://илиhttps://), он является абсолютным. В противном случае URI интерпретируется относительно URI, использованного для списка бандлов. Если URI начинается с/, соответствующий относительный путь отсчитывается от доменного имени, использованного для списка бандлов. (Такое использование относительных путей предназначено для упрощения распространения набора бандлов на большом количестве серверов или CDN с разными доменными именами.) - bundle.<id>.filter
-
Это строковое значение задаёт фильтр объектов, который также должен присутствовать в заголовке этого бандла. Сервер использует это значение, чтобы различать типы бандлов, среди которых клиент может выбрать соответствующие своим фильтрам объектов.
- bundle.<id>.creationToken
-
Это значение — неотрицательное 64-разрядное целое число, используемое для сортировки списка бандлов. Оно используется для загрузки подмножества бандлов во время получения данных, когда
bundle.heuristic=creationToken. - bundle.<id>.location
-
Это строковое значение указывает на реальное местоположение, откуда предоставляется URI бандла. Его можно использовать, чтобы предложить пользователю выбрать URI бандла, либо просто как информационный индикатор того, какой URI бандла выбрал Git. Это полезно только если
bundle.modeимеет значениеany.
Ниже приведён пример списка бандлов в формате конфигурации Git:
[bundle]
version = 1
mode = all
heuristic = creationToken [bundle "2022-02-09-1644442601-daily"]
uri = https://bundles.example.com/git/git/2022-02-09-1644442601-daily.bundle
creationToken = 1644442601 [bundle "2022-02-02-1643842562"]
uri = https://bundles.example.com/git/git/2022-02-02-1643842562.bundle
creationToken = 1643842562 [bundle "2022-02-09-1644442631-daily-blobless"]
uri = 2022-02-09-1644442631-daily-blobless.bundle
creationToken = 1644442631
filter = blob:none [bundle "2022-02-02-1643842568-blobless"]
uri = /git/git/2022-02-02-1643842568-blobless.bundle
creationToken = 1643842568
filter = blob:none В этом примере используется bundle.mode=all, а также эвристика bundle.<id>.creationToken. Кроме того, используются параметры bundle.<id>.filter, чтобы представить два параллельных набора бандлов: один для полных клонов, другой — для частичных клонов без блобов.
Предположим, что этот список бандлов был найден по URI https://bundles.example.com/git/git/, и, следовательно, два бандла без блобов имеют следующие полностью развёрнутые URI:
-
https://bundles.example.com/git/git/2022-02-09-1644442631-daily-blobless.bundle -
https://bundles.example.com/git/git/2022-02-02-1643842568-blobless.bundle
Рекламирование URI бандлов
Если пользователь знает URI бандла для репозитория, который он клонирует, он может вручную указать этот URI с помощью параметра командной строки. Однако хост Git может захотеть сообщать URI бандлов во время клонирования, помогая пользователям, которые не знают об этой возможности.
Для этой возможности требуется лишь, чтобы сервер мог сообщать один или несколько URI бандлов. Это объявление осуществляется с помощью новой возможности протокола версии 2, предназначенной специально для обнаружения URI бандлов.
Клиент может выбрать произвольный URI бандла в качестве варианта or выбрать URI с наилучшей производительностью на основе некоторых предварительных проверок. Поставщик бандлов сам решает, предпочтительнее ли несколько URI, чем один URI, географически распределённый с помощью серверной инфраструктуры.
Клонирование с URI бандлов
Основное назначение URI бандлов — ускорить клонирование. Клиент Git будет взаимодействовать с URI бандлов согласно следующему алгоритму:
-
Пользователь указывает URI бандла с помощью параметра командной строки
--bundle-uriorклиент обнаруживает список бандлов, объявленный сервером Git. -
Если загруженные данные по URI бандла являются бандлом, клиент проверяет заголовки бандла, чтобы убедиться, что необходимые OID коммитов присутствуют в репозитории клиента. Если некоторые из них отсутствуют, клиент откладывает распаковку бандла до тех пор, пока не будут распакованы другие бандлы и эти OID не появятся. Когда все необходимые OID присутствуют, клиент распаковывает эти данные с помощью refspec. Используется refspec
+refs/*:refs/bundles/*. Эти ссылки сохраняются, чтобы во время последующих согласованийgitfetchможно было передавать каждую ссылку из бандла какhave, уменьшая объём данных, передаваемых по протоколу Git. Чтобы разрешить удаление ссылок из этого пространства имён ссылок, Git может ввести пространство имён с нумерацией (например,refs/bundles/<i>/*), чтобы можно было удалять устаревшие ссылки бандлов. -
Если файл является списком бандлов, клиент проверяет
bundle.mode, чтобы определить, относится ли список к типуallилиany.-
Если это
bundle.mode=all, клиент рассматривает все URI бандлов. Список сокращается с учётом параметровbundle.<id>.filter, соответствующих фильтру частичного клонирования репозитория клиента. Затем запрашиваются все URI бандлов. Если предоставлена эвристикаbundle.<id>.creationToken, бандлы загружаются в порядке убывания токена создания; загрузка прекращается, когда в бандле присутствуют все необходимые OID. Затем бандлы можно распаковать в порядке возрастания токена создания. Клиент сохраняет последний токен создания как эвристику, позволяющую избежать будущих загрузок, если в списке бандлов не объявлены бандлы с большими токенами создания. -
Если это
bundle.mode=any, клиент может выбрать любой один URI бандла для проверки. Для выбора URI клиент может использовать различные способы. Если первоначальный выбор не дал результата, клиент также может перейти к другому URI.
-
Обратите внимание: при клонировании предполагается, что потребуются все бандлы, а такие эвристики, как bundle.<uri>.creationToken, можно использовать для загрузки бандлов в хронологическом порядке или параллельно.
Если заданный URI бандла является списком бандлов со значением bundle.heuristic, клиент может сохранить этот URI как выбранный URI бандла. Затем во время последующих вызовов git fetch клиент сможет обращаться напрямую к этому URI.
При загрузке URI бандлов клиент может проверить начальное содержимое, прежде чем загружать весь файл. Это может дать достаточно информации, чтобы определить, является ли URI списком бандлов или бандлом. Если это бандл, клиент может проверить заголовок бандла и выяснить, что все объявленные вершины уже есть в репозитории клиента, после чего отменить оставшуюся загрузку.
Получение данных с URI бандлов
При получении новых данных клиент может решить сначала получить их с серверов бандлов, а затем с исходного удалённого сервера. Это можно сделать с помощью параметра командной строки, но, вероятно, удобнее использовать значение конфигурации, например то, которое указывается при клонировании.
Операция получения данных выполняется по той же процедуре, что и загрузка бандлов из списка бандлов (хотя мы not хотим использовать здесь параллельную загрузку). Ожидается, что процесс завершится, когда все необходимые OID коммитов в тонком бандле уже будут находиться в базе объектов.
При использовании эвристики creationToken клиент может не загружать бандлы, токены создания которых не превышают сохранённый токен создания. После загрузки новых бандлов Git обновляет этот локальный токен создания.
Если поставщик бандлов не предоставляет эвристику, клиенту следует проверить заголовки бандлов до загрузки всех данных бандлов на случай, если вершины бандла уже есть в репозитории клиента.
Условия ошибок
Если во время загрузки данных по URI бандла или по списку бандлов, найденному по этому адресу, клиент Git обнаруживает что-либо неожиданное, Git может проигнорировать эти данные и продолжить работу так, как если бы URI бандла не был указан. Главным источником достоверных данных является удалённый сервер Git, а не URI бандла.
Вот несколько примеров условий ошибок:
-
Клиенту не удаётся подключиться к серверу по заданному URI либо соединение теряется без возможности восстановления.
-
Клиент получает ответ уровня 400 (например,
404NotFoundили401NotAuthorized). Клиенту следует использовать помощник учётных данных, чтобы найти и предоставить учётные данные для URI, но при обработке конкретных ошибок уровня 400 необходимо соблюдать семантику других HTTP-протоколов Git. -
Сервер сообщает о любом другом ответе с ошибкой.
-
Клиент получает данные, которые невозможно разобрать как бандл или список бандлов.
-
Фильтр в бандле не соответствует ожиданиям.
-
Клиент не может распаковать бандлы, поскольку необходимые OID коммитов отсутствуют в базе объектов, а загружать больше нечего.
Есть также ситуации, которые можно считать расточительными, но они не являются условиями ошибок:
-
Загруженные бандлы содержат больше данных, чем запрошено в запросе на клонирование или получение данных. Типичный пример — пользователь запрашивает клонирование с параметром
--single-branch, но загружает бандлы, в которых хранятся все коммиты, достижимые из всех ссылокrefs/heads/*. Сначала это может быть расточительно, однако впоследствии эти объекты могут стать достижимыми после обновления ссылки, важного для клиента. -
Бандлы, загруженные во время
gitfetch, содержат объекты, уже имеющиеся в базе объектов. Вероятно, этого невозможно избежать при использовании бандлов для получения данных, поскольку после «синхронизации» с удалённым сервером клиент почти всегда будет немного опережать серверы бандлов. Дополнительная работа особенно расточительна, если клиент получает данные гораздо чаще, чем сервер вычисляет бандлы: например, если клиент ежечасно выполняет предварительное получение данных в рамках фонового обслуживания, а сервер вычисляет бандлы раз в неделю. Поэтому клиенту не следует использовать URI бандлов для получения данных, если только сервер явно не рекомендует это с помощью значенияbundle.heuristic.
Пример организации поставщика бандлов
Поддержка URI бандлов намеренно спроектирована с учётом различных способов организации данных объектов, которые может выбрать поставщик бандлов. Однако полезно привести здесь полную модель организации, чтобы поставщики могли использовать её в качестве основы.
В этом примере представлена упрощённая модель того, что используется на серверах кэша GVFS (см. раздел ближе к концу этого документа). Эти серверы помогли ускорить клонирование и получение данных из очень больших репозиториев, хотя и с использованием дополнительного программного обеспечения вне Git.
Поставщик бандлов разворачивает серверы в нескольких географических регионах. Каждый сервер управляет собственным набором бандлов. Сервер может отслеживать несколько репозиториев Git, но предоставляет для каждого список бандлов, сформированный на основе шаблона. Например, при зеркалировании репозитория по адресу https://<domain>/<org>/<repo> сервер бандлов может предоставить список бандлов по адресу https://<server-url>/<domain>/<org>/<repo>. Исходный сервер Git может перечислить все эти серверы в режиме «any»:
[bundle]
version = 1
mode = any [bundle "eastus"]
uri = https://eastus.example.com/<domain>/<org>/<repo> [bundle "europe"]
uri = https://europe.example.com/<domain>/<org>/<repo> [bundle "apac"]
uri = https://apac.example.com/<domain>/<org>/<repo> Этот «список списков» является статическим и изменяется только при добавлении или удалении сервера бандлов.
Каждый сервер бандлов управляет собственным набором бандлов. Изначально список бандлов содержит только один бандл, включающий все объекты, полученные при клонировании репозитория с исходного сервера. В списке используется эвристика creationToken, а для бандла создаётся значение creationToken на основе временной метки сервера.
Сервер бандлов регулярно обновляет список, например раз в день. Во время этой задачи сервер получает последнее содержимое с исходного сервера и создаёт бандл, включающий объекты, достижимые из последних ссылок исходного сервера, но отсутствующие в ранее вычисленных бандлах. Этот бандл добавляется в список; при этом необходимо следить, чтобы значение creationToken было строго больше предыдущего максимального значения creationToken.
Когда список бандлов становится слишком большим, например превышает 30 бандлов, самые старые «N минус 30» бандлов объединяются в один. Значение creationToken этого бандла равно максимальному значению creationToken среди объединённых бандлов.
Ниже приведён пример списка бандлов, содержащий только два ежедневных бандла, а не полный список из 30:
[bundle]
version = 1
mode = all
heuristic = creationToken [bundle "2022-02-13-1644770820-daily"]
uri = https://eastus.example.com/<domain>/<org>/<repo>/2022-02-09-1644770820-daily.bundle
creationToken = 1644770820 [bundle "2022-02-09-1644442601-daily"]
uri = https://eastus.example.com/<domain>/<org>/<repo>/2022-02-09-1644442601-daily.bundle
creationToken = 1644442601 [bundle "2022-02-02-1643842562"]
uri = https://eastus.example.com/<domain>/<org>/<repo>/2022-02-02-1643842562.bundle
creationToken = 1643842562 Чтобы не хранить и не предоставлять данные объектов вечно, несмотря на то что они перестали быть достижимыми на исходном сервере, объединение бандлов можно выполнять более тщательно. Вместо абсолютного объединения старых бандлов можно создать бандл, просмотрев более новые бандлы и убедившись, что все необходимые им коммиты доступны в этом объединённом бандле (или в другом из более новых бандлов). Это позволяет «сроку действия» данных объектов, которые не используются новыми коммитами в течение этого периода, истечь. Эти данные могут быть добавлены снова при последующей отправке.
У такой организации данных две основные цели. Во-первых, первоначальное клонирование репозитория ускоряется за счёт загрузки предварительно вычисленных данных объектов из более близкого источника. Во-вторых, команды git fetch могут выполняться быстрее, особенно если клиент не получал данные несколько дней. Однако если клиент не получает данные в течение 30 дней, организация списка бандлов приведёт к повторной загрузке большого объёма данных объектов.
Один из способов сделать такую организацию полезнее для пользователей, часто получающих данные, — создавать бандлы чаще. Например, бандлы можно создавать каждый час, а затем раз в день объединять эти «ежечасные» бандлы в «ежедневный» бандл. По истечении 30 дней ежедневные бандлы объединяются с самым старым бандлом.
Рекомендуется повторить эту стратегию бандлов с фильтром blob:none, если клиенты этого репозитория планируют использовать частичные клоны без блобов. Список бандлов без блобов находится в том же списке, что и полные бандлы, но для разделения этих двух групп используется ключ bundle.<id>.filter. Для очень больших репозиториев поставщик бандлов может захотеть only предоставлять бандлы без блобов.
План реализации
Этот проектный документ представлен отдельно как документ с описанием желаемого развития, цель которого — реализовать все упомянутые возможности клиента в рамках нескольких серий патчей. Ниже приведён возможный план реализации этих возможностей:
-
Добавить поддержку URI бандлов в
gitcloneс параметром--bundle-uri. Это включает новый режимgitfetch--bundle-uri, который будет использоваться как реализация дляgitclone. Изначально предполагается, что по заданному URI находится один бандл. -
Реализовать возможность разбирать список бандлов по URI бандла и обновить логику
gitfetch--bundle-uri, чтобы корректно различать параметрыbundle.mode. При проектировании этой возможности необходимо предусмотреть, чтобы разбор формата конфигурации передавал список пар «ключ-значение» логике обработки списка бандлов. -
Создать команду протокола версии 2
bundle-uri, чтобы серверы Git могли сообщать URI бандлов с помощью пар «ключ-значение». Подключить её к существующему механизму передачи пар «ключ-значение» логике обработки списка бандлов. Обеспечить возможность обнаружения этих URI бандлов с помощьюgitcloneи первоначальной подготовки репозитория клиента из данных бандлов. (Эта возможность включается по выбору с помощью параметра конфигурации и параметра командной строки.) -
Добавить клиенту поддержку ключа конфигурации
bundle.heuristicи эвристикиbundle.<id>.creationToken. Когдаgitcloneобнаруживает URI бандла со значениемbundle.heuristic, он настраивает репозиторий клиента так, чтобы при последующих командахgitfetch<remote> проверялся этот URI бандла. -
Добавить возможность обнаруживать URI бандлов во время
gitfetchи настраивать URI бандла для последующего получения данных, если задано значениеbundle.heuristic. -
Реализовать эвристику «проверки заголовков», чтобы уменьшить объём загружаемых данных, если эвристика
bundle.<id>.creationTokenнедоступна.
По мере рассмотрения этих возможностей план может обновляться. Мы также ожидаем, что по мере развития этой возможности и её использования в реальных сценариях будут разрабатываться и реализовываться новые решения.
Связанные разработки: URI pack-файлов
В протоколе Git уже есть возможность, с помощью которой сервер Git может перечислить набор URL вместе с ответом pack-файлом на запрос клиента. Предполагается, что затем клиент загрузит pack-файлы по этим адресам, чтобы получить полное представление об ответе.
Этот механизм используется сервером Gerrit (реализованным на JGit) и эффективно снижает нагрузку на ЦП и повышает производительность клонирования для пользователей.
Существенный недостаток этого механизма состоит в том, что исходный сервер должен знать exactly, что находится в этих pack-файлах, а сами pack-файлы должны оставаться доступными пользователю некоторое время после ответа сервера. Эту связь между исходным сервером и данными pack-файлов трудно поддерживать.
Кроме того, эту реализацию крайне сложно применить для получения данных.
Связанные разработки: серверы кэша GVFS
Протокол GVFS [2] — это набор конечных точек HTTP, разработанный независимо от проекта Git ещё до появления частичного клонирования в Git. Одна из особенностей этого протокола — идея «кэш-сервера», который можно разместить рядом со сборочными машинами или в офисах разработчиков, чтобы передавать данные Git, не перегружая центральный сервер.
Конечная точка, которой известен VFS for Git, — это конечная точка GET /gvfs/objects/{oid}, позволяющая загружать объект по запросу. Это важная часть виртуализации файловой системы в этом продукте.
Однако более тонкая потребность — это конечная точка GET /gvfs/prefetch?lastPackTimestamp=<t>. Получив необязательную временную метку, кэш-сервер отвечает списком заранее вычисленных pack-файлов, содержащих коммиты и деревья, добавленные в соответствующие временные интервалы.
Кэш-сервер вычисляет эти pack-файлы «предварительной загрузки» по следующей стратегии:
-
Каждый час создаётся «почасовой» pack-файл с указанной временной меткой.
-
Каждую ночь предыдущие 24 почасовых pack-файла объединяются в «ежедневный» pack-файл.
-
Каждую ночь все pack-файлы предварительной загрузки старше 30 дней объединяются в один pack-файл.
Когда пользователь выполняет gvfs clone или scalar clone в репозитории с кэш-серверами, клиент запрашивает все pack-файлы предварительной загрузки — не более 24 + 30 + 1 pack-файлов, содержащих только коммиты и деревья. Затем клиент запрашивает ссылки у исходного сервера и пытается выполнить checkout по ссылке на вершину. (Существует дополнительная конечная точка, позволяющая получить все деревья, достижимые из указанного коммита, на случай, если этот коммит ещё не входит в pack-файл предварительной загрузки.)
Во время выполнения git fetch хук обращается к конечной точке предварительной загрузки, используя самую позднюю временную метку из ранее загруженного pack-файла предварительной загрузки. Загружается только список pack-файлов с более поздними временными метками. Большинство пользователей выполняют fetch каждый час, поэтому получают не более одного почасового pack-файла предварительной загрузки. Пользователи, чьи компьютеры были выключены или которые по другим причинам не выполняли fetch более 30 дней, могут повторно загрузить все pack-файлы предварительной загрузки. Такое случается редко.
Важно отметить, что клиенты всегда обращаются к исходному серверу за объявлением ссылок, поэтому ссылки часто «опережают» данные предварительно загруженных pack-файлов. Отсутствующие объекты загружаются по запросу с помощью запросов GET gvfs/objects/{oid}, когда они нужны такой команде, как git checkout или git log. Некоторые оптимизации Git отключают проверки, которые могли бы привести к чрезмерно активной загрузке таких объектов по запросу.
См. также
[1] https://lore.kernel.org/git/RFC-cover-00.13-0000000000-20210805T150534Z-avarab@gmail.com/ Более раннее предложение RFC о функции URI пакетов.
[2] https://github.com/microsoft/VFSForGit/blob/master/Protocol.md Протокол GVFS
© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/bundle-uri