Русский ▾ Topics ▾ Latest version ▾ git-bundle last updated in 2.48.0

НАЗВАНИЕ

git-bundle - Перемещение объектов и ссылок с помощью архива

ОБЗОР

git bundle create [-q | --quiet | --progress]
		    [--version=<версия>] <файл> <аргументы-git-rev-list>
git bundle verify [-q | --quiet] <файл>
git bundle list-heads <файл> [<имя-ссылки>…​]
git bundle unbundle [--progress] <файл> [<имя-ссылки>…​]

ОПИСАНИЕ

Создание, распаковка и управление файлами «bundle» (пакет). Пакеты используются для «офлайн»-передачи объектов Git без активного «сервера» на другой стороне сетевого соединения.

Они могут использоваться для создания как инкрементальных, так и полных резервных копий репозитория (см. пример «полного резервного копирования» в «ПРИМЕРАХ»), а также для передачи состояния ссылок из одного репозитория в другой (см. второй пример).

Команды Git, которые получают или иным образом «читают» по протоколам, таким как ssh:// и https://, также могут работать с файлами пакетов. Можно выполнить git-clone[1] нового репозитория из пакета, использовать git-fetch[1] для получения из него и вывести список содержащихся в нём ссылок с помощью git-ls-remote[1]. Соответствующей поддержки «записи» нет, т.е. git push в пакет не поддерживается.

ФОРМАТ ПАКЕТА

Пакеты (bundle) — это файлы .pack (см. git-pack-objects[1]) с заголовком, указывающим, какие ссылки содержатся в пакете.

Как и сам формат упакованного архива, пакеты могут быть либо самодостаточными, либо создаваться с использованием исключений. См. раздел «ПРЕДВАРИТЕЛЬНЫЕ ТРЕБОВАНИЯ К ОБЪЕКТАМ» ниже.

Пакеты, созданные с использованием исключений редакций, представляют собой «тонкие пакеты» (thin packs), созданные с помощью опции --thin в git-pack-objects[1], и распаковываются с помощью опции --fix-thin в git-index-pack[1].

Не существует опции для создания «толстого пакета» (thick pack) при использовании исключений редакций, и пользователям не следует беспокоиться о различии. Используя «тонкие пакеты», пакеты, созданные с исключениями, имеют меньший размер. То, что они «тонкие» внутри, здесь отмечено лишь как любопытный факт и как ссылка на другую документацию.

См. gitformat-bundle[5] для получения более подробной информации и обсуждение «тонкого пакета» в gitformat-pack[5] для дальнейших подробностей.

ПАРАМЕТРЫ

create [параметры] <файл> <аргументы-git-rev-list>

Используется для создания пакета с именем файл. Для этого требуются аргументы <аргументы-git-rev-list> для определения содержимого пакета. параметры содержат параметры, специфичные для подкоманды git bundle create. Если файл равен -, пакет записывается в stdout.

verify <файл>

Используется для проверки того, что файл пакета действителен и будет чисто применён к текущему репозиторию. Это включает проверки самого формата пакета, а также проверку того, что предварительно требуемые коммиты существуют и полностью связаны в текущем репозитории. Затем git bundle выводит список отсутствующих коммитов, если таковые имеются. Наконец, выводится информация о дополнительных возможностях, таких как «фильтр объектов». Для получения дополнительной информации см. «Возможности» в gitformat-bundle[5]. Код завершения равен нулю при успехе, но будет ненулевым, если файл пакета недействителен. Если файл равен -, пакет читается из stdin.

list-heads <файл>

Выводит список ссылок, определённых в пакете. Если за ним следует список ссылок, выводятся только ссылки, соответствующие указанным. Если файл равен -, пакет читается из stdin.

unbundle <файл>

Передаёт объекты в пакете в git index-pack для хранения в репозитории, затем выводит имена всех определённых ссылок. Если указан список ссылок, выводятся только ссылки, соответствующие тем, что в списке. Эта команда является внутренней (plumbing) и предназначена для вызова только git fetch. Если файл равен -, пакет читается из stdin.

<git-rev-list-args>

Список аргументов, приемлемых для git rev-parse и git rev-list (и содержащий именованную ссылку, см. УКАЗАНИЕ ССЫЛОК ниже), который определяет конкретные объекты и ссылки для передачи. Например, master~10..master заставляет текущую ссылку master быть упакованной вместе со всеми объектами, добавленными, начиная с её 10-го коммита-предка. Не существует явного ограничения на количество ссылок и объектов, которые могут быть упакованы.

[<refname>…​]

Список ссылок, используемый для ограничения ссылок, сообщаемых как доступные. Это в основном используется git fetch, который ожидает получить только те ссылки, которые были запрошены, а не обязательно всё, что в пакете (в этом случае git bundle действует как git fetch-pack).

--progress

Прогресс по умолчанию направляется в стандартный вывод ошибок, если этот поток подключен к терминалу. Флаг -q меняет это умолчание: с этим флагом прогресс направляется в стандартный вывод ошибок даже в том случае, когда этот поток не подключен к терминалу.

--version=<версия>

Указать версию пакета. Версия 2 — это старый формат и может использоваться только с репозиториями SHA-1; более новая версия 3 содержит возможности, допускающие расширения. По умолчанию используется самый старый из поддерживаемых форматов, основанный на используемом алгоритме хеширования.

-q
--quiet

Этот флаг заставляет команду не сообщать о своём прогрессе в стандартный поток ошибок.

УКАЗАНИЕ ССЫЛОК

Редакции должны сопровождаться именами ссылок для упаковки в пакет. Кроме того, можно использовать --all для упаковки всех ссылок.

Может быть упаковано более одной ссылки, и может быть указано более одного набора предварительно требуемых объектов. Упакованные объекты — это те, которые не содержатся в объединении предварительных требований.

Команда git bundle create разрешает имена ссылок за вас, используя те же правила, что и git rev-parse --abbrev-ref=loose. Каждое предварительное требование может быть указано явно (например, ^master~10) или неявно (например, master~10..master, --since=10.days.ago master).

Все эти простые случаи допустимы (при условии, что у нас есть ветки «master» и «next»):

$ git bundle create master.bundle master
$ echo master | git bundle create master.bundle --stdin
$ git bundle create master-and-next.bundle master next
$ (echo master; echo next) | git bundle create master-and-next.bundle --stdin

И эти тоже (и те же примеры, но с опущенным --stdin):

$ git bundle create recent-master.bundle master~10..master
$ git bundle create recent-updates.bundle master~10..master next~5..next

Имя редакции или диапазон, правая часть которого не может быть разрешена в ссылку, не принимается:

$ git bundle create HEAD.bundle $(git rev-parse HEAD)
fatal: Отказ от создания пустого пакета.
$ git bundle create master-yesterday.bundle master~10..master~5
fatal: Отказ от создания пустого пакета.

ПРЕДВАРИТЕЛЬНЫЕ ТРЕБОВАНИЯ К ОБЪЕКТАМ

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

Передача редакции, такой как new, в git bundle create создаст файл пакета, содержащий все объекты, достижимые из редакции new. Этот пакет может быть распакован в любом репозитории для получения полной истории, ведущей к редакции new:

$ git bundle create full.bundle new

Диапазон редакций, такой как old..new, создаст файл пакета, для возможности «распаковки» которого потребуется существование редакции old (и любых объектов, достижимых из неё):

$ git bundle create full.bundle old..new

Самодостаточный пакет без каких-либо предварительных требований может быть извлечён куда угодно, даже в пустой репозиторий, или из него можно клонировать (т.е. new, но не old..new).

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

Если вы хотите предоставить тот же набор ссылок, который получил бы клон непосредственно из исходного репозитория, используйте --branches --tags для <аргументы-git-rev-list>.

Команда git bundle verify может использоваться для проверки того, есть ли в вашем репозитории-получателе необходимые предварительно требуемые коммиты для пакета.

ПРИМЕРЫ

Мы рассмотрим два случая:

  1. Создание полной резервной копии репозитория

  2. Передача истории репозитория на другую машину, когда две машины не имеют прямого соединения

Сначала рассмотрим полную резервную копию репозитория. Следующая команда создаст полную резервную копию репозитория в том смысле, что все ссылки включены в пакет:

$ git bundle create backup.bundle --all

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

Вы можете позже восстановить этот репозиторий, используя, например, git-clone[1]:

$ git clone backup.bundle <новый-каталог>

Для следующего примера предположим, что вы хотите передать историю из репозитория R1 на машине A в другой репозиторий R2 на машине B. По какой-то причине прямое соединение между A и B не разрешено, но мы можем перемещать данные с A на B через какой-либо механизм (CD, электронная почта и т.д.). Мы хотим обновить R2 разработкой, выполненной в ветке master в R1.

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

machineA$ cd R1
machineA$ git bundle create file.bundle master
machineA$ git tag -f lastR2bundle master

Затем вы передаёте file.bundle на целевую машину B. Поскольку этот пакет не требует извлечения каких-либо существующих объектов, вы можете создать новый репозиторий на машине B, клонировав из него:

machineB$ git clone -b master /home/me/tmp/file.bundle R2

Это определит внешний репозиторий с именем «origin» в результирующем репозитории, который позволит вам получать (fetch) и извлекать (pull) из пакета. Файл $GIT_DIR/config в R2 будет иметь запись, подобную этой:

[remote "origin"]
    url = /home/me/tmp/file.bundle
    fetch = refs/heads/*:refs/remotes/origin/*

Чтобы обновить полученный репозиторий mine.git, вы можете выполнить fetch или pull после замены пакета, хранящегося по адресу /home/me/tmp/file.bundle, на инкрементальные обновления.

После дополнительной работы в исходном репозитории вы можете создать инкрементальный пакет для обновления другого репозитория:

machineA$ cd R1
machineA$ git bundle create file.bundle lastR2bundle..master
machineA$ git tag -f lastR2bundle master

Затем вы передаёте пакет на другую машину, чтобы заменить /home/me/tmp/file.bundle, и выполняете pull из него.

machineB$ cd R2
machineB$ git pull

Если вы знаете, до какого коммита в предполагаемом репозитории-получателе должны быть необходимые объекты, вы можете использовать это знание для указания предварительных требований, задавая точку отсечки для ограничения редакций и объектов, попадающих в результирующий пакет. В предыдущем примере для этой цели использовалась метка lastR2bundle, но вы можете использовать любые другие параметры, которые вы бы передали команде git-log[1]. Вот ещё примеры:

Вы можете использовать метку, присутствующую в обоих:

$ git bundle create mybundle v1.0.0..master

Вы можете использовать предварительное требование, основанное на времени:

$ git bundle create mybundle --since=10.days master

Вы можете использовать количество коммитов:

$ git bundle create mybundle -10 master

Вы можете запустить git-bundle verify, чтобы увидеть, можно ли извлечь данные из пакета, созданного с предварительным требованием:

$ git bundle verify mybundle

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

Пакет с точки зрения репозитория-получателя — это просто обычный репозиторий, из которого он получает (fetch) или извлекает (pull). Вы можете, например, сопоставлять ссылки при получении:

$ git fetch mybundle master:localRef

Вы также можете увидеть, какие ссылки он предлагает:

$ git ls-remote mybundle

ОБСУЖДЕНИЕ

Наивный способ сделать полную резервную копию репозитория — использовать что-то вроде cp -r <репозиторий> <назначение>. Это не рекомендуется, поскольку в репозиторий может производиться запись во время операции копирования. В свою очередь, некоторые файлы в <назначение> могут быть повреждены.

Вот почему для создания резервных копий репозитория рекомендуется использовать инструменты Git, либо с помощью этой команды, либо с помощью, например, git-clone[1]. Но имейте в виду, что эти инструменты не помогут вам создать резервную копию состояния, отличного от ссылок и коммитов. Другими словами, они не помогут вам создать резервную копию содержимого индекса, рабочего каталога, тайника (stash), конфигурации репозитория, перехватчиков (hooks) и т.д.

См. также gitfaq[7], раздел «ПЕРЕДАЧИ» (TRANSFERS) для обсуждения проблем, связанных с синхронизацией файлов между системами.

ФОРМАТ ФАЙЛА

GIT

Является частью пакета git[1]