Команда git-bundle: опции, ключи и примеры использования
Общие команды – Общие команды, присущие различным операционным системам.
Переведено в рамках проекта tldr-ru. Licensed under the CC-BY (original work).

git bundle
Упаковать объекты и ссылки (refs) в архив.
- Создать файл пакета, который содержит все объекты и ссылки указанной ветки:
- Создать файл пакета для всех веток репозитория:
- Создать бандл-файл для последних 5 коммитов текущей ветки:
- Создать бандл для объектов за последние 7 дней:
- Проверяет на правильность данный бандл. Также проверяет, может ли он быть применён к текущему репозиторию:
- Вывести на стандартный поток вывода список всех ссылок, содержащихся в данном бандле:
- Распаковать указанную ветку из бандла в текущий репозиторий:
Примеры кода, демонстрирующие общие подходы в программировании или же решающие небольшие прикладные задачи. Языки программирования и библиотеки, позволяющие эффективно решать задачи разработки. Объектно-ориентированное программирование, функциональное программирование и прочие подходы и …

Трюки Bash
Полезные заметки по работе с командной строкой: bash и прочие *sh. Однострочники, скрипты, позволяющие решать большие и малые задачи администрирования и настройки Юникс систем. Zsh для современного MacOS, Bash для …

Заметки о настройке различных IT-штуковин. Настройка, допиливание, полировка. Конфигурируем приложения и тюнингуем сервера. Полезные параметры и ключи запуска программ. Увеличиваем скорость, уменьшаем отклик, ускоряем работу и улучшаем результаты работы. Объясняем …

Терминал/Консоль
Команды и инструкции терминала (консоли) Linux, MacOS, Windows и прочих операционных систем. Трюки и особенности командных оболочек, скрипты для администрирования Unix. Программирование и скриптование Windows и Linux, тонкая настройка Macos. …

Также может быть вам интересно:
- Как получить дерево директорий на Bash одним однострочником
- Python: Функции
- Python: Встроенные типы данных (list, set, dict, etc)
- Python: типы данных, переменные, логическое ветвление и циклы
- Как сделать свою middleware в Django (с примерами)
Свежее на «Цифре»
MessageId или как дебажить систему с минимумом проблем
Программы, 09.09.2023
Проверочный список для выпуска промышленных приложений с иллюстрациями
Работа и управление, 30.07.2023
В Google Pixel и Windows Snipping Tool есть возможность восстановления обрезанных изображений
Новости, 23.03.2023
Два подарка «под ёлочку» от Heroes of Might and Magic
Новости, 25.12.2022
Вышел Pulsar – редактор кода на основе Atom
Новости, 25.12.2022
Ленивый backup PostgreSQL
Программы, 17.12.2022
Google анонсировала OSV-Scanner: сканер уязвимостей в программных проектах
Новости, 16.12.2022

Gitea запускает коммерческую версию, а недовольные – форк Forĝejo
На днях группа бывших разработчиков Gitea решили создать на базе хостинга кода Gitea свою версию проекта – «Forgejo». Причиной тому …

Пользователи и их создание в Django — своя регистрация на сайте
Если вашим сайтом должны активно пользоваться несколько человек, то полезно их различать, а значит — надо уметь создавать пользователей, либо …

Новый синтаксис старой команды with в Python 3.10
Как же долго моё чувство прекрасного страдало… Но в Python 3.10 появился новый парсер синтаксических конструкций Python!

Добавляем постраничную пагинацию на Django сайт
На сайтах часто встречаются многостраничные объекты: список товаров, список заметок и т.д. Поэтому важно уметь добавить навигацию по страницам на …

Новый оператор match-case в Python
В новой версии Python (3.10) появится новый оператор. Новый оператор сопоставления по шаблону (match-case).

Нет слов, одни. однострочники
На днях вышел пост со списком полезных однострочников для JavaScript программистов. Памятуя Perl-овую молодость, заглянул туда.

Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)
В Django вы можете передавать данные в шаблоны посредством контекстов. Контекст передаётся из контроллера (view в терминах Django), однако, если …

Пример своей консольной команды в Django проекте
Если вы работали с Django проектом, то, скорее всего, запускали команды из консоли (manage.py). В Django есть простой способ писать …

Разграничение прав доступа на Django сайте
Почти на любом веб-сайте необходимо разделять пользователей на группы и предоставлять им разные возможности. В Django есть довольно серьёзная система …
MrDekk

Время — лучший учитель! Жаль, что оно убивает своих учеников.
© 2019. All rights reserved.
Передача веток и коммитов между двумя GIT-репозиториями
Случилась такая задача. Есть два git-репозитория (один из которых ко всему прочему соединен с SVN через git-svn). Между ними необходимо передавать ветки и коммиты. Если бы они имели прямую связь через файловую систему или например через http, особых проблем бы не было. Однако, никакой связи кроме человека с флэшкой между этими репозиториями нет. Поэтому пришлось изобретать некий workflow который позволил бы эффективно эту проблему решить.
Вот картинка того, что требуется сделать:

Решить эту проблему можно тремя способами:
- Скопировать весь локальный репозиторий одной стороны (например, Repo A) и перенести его на флэшке рядом с репозиторием (Repo B) чтобы между ними можно было установить прямую связь через локальную файловую систему
- Использовать механизм патчей (git am)
- Использовать механизм пакетов git’а (git bundles)
Первый способ нам не подошел. Хотя бы потому, что репозиторий весит около 1.5 ГБ в сжатом виде. А заливать его приходилось в том числе через RDP соединение. Хотя если у вас есть такая возможность – это самый правильный и самый лучший вариант. Нам увы не подошел, поэтому идем дальше.
Второй способ мы даже активно использовали. Workflow там примерно следующий. С какого-то определенного коммита мы делаем набор патчей для каждого коммита выбранной ветки. На другом репозитории мы переключаемся (или создаем если такой ветки еще нет) на нужную ветку и делаем Apply Patch Serial. В принципе это все работает, но есть проблемы. Проблема первая – фактически в двух репозиториях мы имеем две разные ветки, хоть они одинаково и называются. И содержат разные коммиты, хоть и они содержат одно и то же. Кроме того, возникают нетривиальные вещи связанные с разрешением коллизий. Вообщем, достаточно громоздко и сложно, хотя и работает.
Третий способ – git bundles. Вот его и рассмотрим.
Начнем с того, что git bundle – это такой специальный файл. В который во-первых упакованы нужные ветки и нужные коммиты (вы их указываете сами). Во-вторых, он может представляться как удаленный git-репозиторий, который можно добавить в remotes и работать с ним как с полноценным удаленным репозиторием. Скажем так – этот подход – лайт версия первого подхода, когда вы тащите за собой весь репозиторий. Только здесь вы тащите один файл с тем, что надо. Места он правда может занять тоже весьма нехило, но в общем гораздо меньше (при правильном подходе), чем весь репозиторий.
Теперь давайте рассмотрим как это дело провернуть. Предположим у вас есть репозиторий A из которого необходимо перетащить ветку в репозиторий B (который пуст).
Имеем несколько файлов в репозитории A:


Создание бандлов
Теперь нам нужно создать (пересоздать) бандл. Тут два пути – если он уже был создан когда-то, или же его еще не было.
Случай, когда мы создаем новый бандл
# Создаем новый бандл для ветки мастер (веток может быть несколько) $ git bundle create ../master.bundle master # Помечаем последний коммит на ветке мастер который мы себе забрали (чтобы в следующий раз не тащить все) # lastR2bundle - просто некоторое имя $ git tag -f lastR2bundle master
Случай, если бандл уже создавали (и появились новые изменения)

# Создаем бандл, но уже с указанием места, с которого его создавали в предыдущий раз $ git bundle create ../master2.bundle lastR2bundle..master # Обновляем указатель последнего коммита бандла $ git tag -f lastR2bundle master
Разворачивание бандлов
Теперь бандл у нас есть, необходимо развернуть (обновить) его на другом репозитории RepoB.
В случае если бандл мы принесли первый раз и репозитория нет.
Тогда можно просто склонировать репозиторий прямо с бандла:
# Клонируем репозиторий с бандла в текущую папку $ git clone -b master C:/Temp/gittest/master.bundle .
Ветка автоматически разворачивается до текущего состояния (флаг -b master указывает нужную ветку)

Случай, когда бандл принесли первый раз, но репозиторий уже есть
Тут несколько сложнее, необходимо зайти в папку .git в корне репозитория и отредактировать там файл config
# создаем новый remote с именем RepoA [remote "RepoA"] # указываем путь до бандла url = C:/Temp/gittest/master.bundle # указываем способ получения веток из бандла fetch = +refs/heads/*:refs/remotes/RepoA/*
После этого делаем
$ git pull RepoA master
И получаем выгруженную историю из бандла.
Случай, когда бандл уже приносили
В этом случае достаточно заменить старую версию бандла новым, и сделать git pull. Бандлы, сделанные не с самого «начала времен» а с определенного места занимают не так много места.
Надеюсь всем было все понятно и это поможет вам вести удобную разработку с использованием git’а.
P.S. Механизм бандлов работает в обе стороны, изменения в нашей схеме можно переносить не только из RepoA в RepoB, но и наоборот.
7.12 Инструменты Git — Создание пакетов
Помимо рассмотренных ранее основных способов передачи данных Git по сети (HTTP, SSH и т. п.), существует ещё один способ, который обычно не используется, но в некоторых случаях может быть весьма полезным.
Git умеет «упаковывать» свои данные в один файл. Это может быть полезным в разных ситуациях. Может быть, ваша сеть не работает, а вы хотите отправить изменения своим коллегам. Возможно, вы работаете откуда-то извне офиса и не имеете доступа к локальной сети по соображениям безопасности. Может быть, ваша карта беспроводной/проводной связи просто сломалась. Возможно, у вас в данный момент нет доступа к общему серверу, а вы хотите отправить кому-нибудь по электронной почте обновления, но передавать 40 коммитов с помощью format-patch не хотите.
В этих случаях вам может помочь команда git bundle . Она упакует всё, что в обычной ситуации было бы отправлено по сети командой git push , в бинарный файл, который вы можете передать кому-нибудь по электронной почте или поместить на флешку и затем распаковать в другом репозитории.
Рассмотрим простой пример. Допустим, у вас есть репозиторий с двумя коммитами:
$ git log commit 9a466c572fe88b195efd356c3f2bbeccdb504102 Author: Scott Chacon Date: Wed Mar 10 07:34:10 2010 -0800 Second commit commit b1ec3248f39900d2a406049d762aa68e9641be25 Author: Scott Chacon Date: Wed Mar 10 07:34:01 2010 -0800 First commit
Если вы хотите отправить кому-нибудь этот репозиторий, но не имеете доступа на запись к общей копии репозитория или просто не хотите его настраивать, то вы можете упаковать его командой git bundle create .
$ git bundle create repo.bundle HEAD master Counting objects: 6, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (6/6), 441 bytes, done. Total 6 (delta 0), reused 0 (delta 0)
В результате вы получили файл repo.bundle , в котором содержатся все данные, необходимые для воссоздания ветки master репозитория. Команде bundle необходимо передать список или диапазон коммитов, которые вы хотите добавить в пакет. Если вы намереваетесь использовать пакет для того, чтобы клонировать репозиторий где-нибудь ещё, вы должны добавить в этот список HEAD, как это сделали мы.
Вы можете отправить файл repo.bundle кому-нибудь по электронной почте или скопировать его на USB-диск, тем самым легко решив исходную проблему.
С другой стороны, допустим, вы получили файл repo.bundle и хотите поработать над этим проектом. Вы можете клонировать репозиторий из бинарного файла в каталог, почти также как вы делаете это при использовании URL.
$ git clone repo.bundle repo Cloning into 'repo'. . $ cd repo $ git log --oneline 9a466c5 Second commit b1ec324 First commit
Если при создании пакета вы не указали в списке ссылок HEAD, то при распаковке вам потребуется указать -b master или какую-либо другую ветку, включённую в пакет, иначе Git не будет знать, на какую ветку ему следует переключиться.
Теперь предположим, что вы сделали три коммита и хотите отправить их обратно в виде пакета на USB-флешке или по электронной почте.
$ git log --oneline 71b84da Last commit - second repo c99cf5b Fourth commit - second repo 7011d3d Third commit - second repo 9a466c5 Second commit b1ec324 First commit
Во-первых, нам нужно определить диапазон коммитов, которые мы хотим включить в пакет. В отличие от сетевых протоколов, которые сами выясняют минимальный набор данных, который нужно передать по сети, в данном случае мы должны сделать это сами вручную. В данном примере вы можете сделать, как раньше и упаковать полностью весь репозиторий, но будет лучше упаковать только изменения — три коммита, сделанные локально.
Для того, чтобы сделать это, вы должны вычислить различия. Как мы рассказывали в Диапазоны коммитов, вы можете указать диапазон коммитов несколькими способами. Для того, чтобы получить три коммита из нашей основной ветки, которые отсутствовали в изначально клонированной ветке, мы можем использовать запись вида origin/master..master или master ^origin/master . Вы можете проверить её с помощью команды log .
$ git log --oneline master ^origin/master 71b84da Last commit - second repo c99cf5b Fourth commit - second repo 7011d3d Third commit - second repo
Так что теперь у нас есть список коммитов, которые мы хотим включить в пакет, давайте упакуем их. Сделаем мы это с помощью команды git bundle create , указав имя выходного пакета и диапазон коммитов, которые мы хотим включить в него.
$ git bundle create commits.bundle master ^9a466c5 Counting objects: 11, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (9/9), 775 bytes, done. Total 9 (delta 0), reused 0 (delta 0)
В результате в нашем каталоге появился файл commits.bundle . Если мы отправим его нашему коллеге, то он сможет импортировать пакет в исходный репозиторий, даже если в репозитории была проделана некоторая работа параллельно с нашей.
При получении пакета коллега перед импортом его в свой репозиторий может проверить пакет, просмотрев его содержимое. Лучшей командой для этого является bundle verify , которая может проверить, что файл действительно является корректным Git-пакетом и что у вас есть все необходимые предки коммитов для правильного его восстановления.
$ git bundle verify ../commits.bundle The bundle contains 1 ref 71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master The bundle requires these 1 ref 9a466c572fe88b195efd356c3f2bbeccdb504102 second commit ../commits.bundle is okay
Если автор создал пакет только с последними двумя коммитами, которые он сделал, а не со всеми тремя, то исходный репозиторий не сможет импортировать этот пакет, так как у него отсутствует необходимая история. В таком случае команда verify вернёт нечто подобное:
$ git bundle verify ../commits-bad.bundle error: Repository lacks these prerequisite commits: error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 Third commit - second repo
Однако, наш первый пакет корректен, поэтому мы можем извлечь коммиты из него. На случай если вы захотите увидеть ветки пакета, которые могут быть импортированы, существует команда для отображения только списка веток:
$ git bundle list-heads ../commits.bundle 71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
Подкоманда verify также выводит список веток. Если цель состоит в том, чтобы увидеть, что может быть извлечено из пакета, то вы можете использовать команды fetch или pull для импорта коммитов. Ниже мы ветку master из пакета извлекаем в ветку other-master нашего репозитория:
$ git fetch ../commits.bundle master:other-master From ../commits.bundle * [new branch] master -> other-master
Теперь мы можем увидеть, какие коммиты мы импортировали в ветку other-master так же, как и любые коммиты, которые мы сделали в то же время в нашей собственной ветке master .
$ git log --oneline --decorate --graph --all * 8255d41 (HEAD, master) Third commit - first repo | * 71b84da (other-master) Last commit - second repo | * c99cf5b Fourth commit - second repo | * 7011d3d Third commit - second repo |/ * 9a466c5 Second commit * b1ec324 First commit
Таким образом, команда git bundle может быть, действительно, полезной для организации совместной работы или для выполнения сетевых операций, когда у вас нет доступа к соответствующей сети или общему репозиторию.
Бандлы и чарты
Бандл — это способ дистрибуции чарта и связанных с ним образов как единого целого.
Командой werf bundle publish можно опубликовать чарт и связанные образы для дальнейшего развёртывания с werf. При этом для развёртывания доступ к Git-репозиторию приложения больше не потребуется.
Эта же команда подходит для публикации чарта. Опубликованный в OCI-репозиторий чарт может использоваться в качестве основного или зависимого чарта с werf, Helm, Argo CD, Flux и другими решениями.
При упаковке werf автоматически добавляет следующие данные в чарт:
- имена собираемых образов и их динамических тегов в Values чарта;
- значения, переданных через параметры командной строки или переменные окружения, в Values чарта;
- глобальные пользовательские и служебные аннотации и лейблы для добавления в ресурсы чарта при развёртывании командой werf bundle apply .
Опубликованный бандл (чарт и связанные с ним образы) можно копировать в другой репозиторий container registry или выгружать в/из архива с помощью одной команды werf bundle copy .
Аутентификация в container registry
Перед работой с образами необходимо аутентифицироваться в container registry. Сделать это можно командой werf cr login:
werf cr login
# Login with username and password from command line werf cr login -u username -p password registry.example.com # Login with token from command line werf cr login -p token registry.example.com # Login into insecure registry (over http) werf cr login --insecure-registry registry.example.com
В случае использования команды ci-env с поддерживаемыми CI/CD-системами аутентификация во встроенные container registry выполняется в рамках команды, поэтому использование команды werf cr login в этом случае не требуется.
Публикация бандла
Опубликовать бандл в OCI-репозиторий можно следующим способом:
-
Создайте werf.yaml , если его ещё нет:
# werf.yaml: project: mybundle configVersion: 1
.helm/ charts/ templates/ crds/ files/ Chart.yaml values.yaml values.schema.json LICENSE README.md
werf bundle publish --repo example.org/bundles/mybundle
Публикация нескольких бандлов из одного Git-репозитория
Разместите .helm с содержимым чарта и соответствующий ему werf.yaml в отдельную директорию для каждого бандла:
bundle1/ .helm/ templates/ # . werf.yaml bundle2/ .helm/ templates/ # . werf.yaml
Теперь опубликуйте каждый бандл по отдельности:
cd bundle1 werf bundle publish --repo example.org/bundles/bundle1 cd ../bundle2 werf bundle publish --repo example.org/bundles/bundle2
Исключение файлов или директорий из публикуемого чарта
Файл .helmignore , находящийся в корне чарта, может содержать фильтры по именам файлов, при соответствии которым файлы или директории не будут добавляться в чарт при публикации. Формат правил такой же, как и в .gitignore, за исключением:
- ** не поддерживается;
- ! в начале строки не поддерживается;
- .helmignore не исключает сам себя по умолчанию.
Также опция —disable-default-values для команды werf bundle publish позволяет исключить из публикуемого чарта файл values.yaml .
Указание версии чарта при публикации
По умолчанию чарт публикуется с тегом latest . Указать иной тег, например, семантическую версию для публикуемого чарта, можно опцией —tag :
werf bundle publish --repo example.org/bundles/mybundle --tag v1.0.0
Результат: опубликован чарт example.org/bundles/mybundle:v1.0.0 .
Если при публикации будет обнаружено, что в OCI-репозитории уже существует чарт с таким тегом, то чарт в репозитории будет перезаписан.
Изменение версии опубликованного чарта
Для изменения тега уже опубликованного чарта скопируйте бандл с новым тегом с помощью команды werf bundle copy , например:
werf bundle copy --from example.org/bundles/mybundle:v1.0.0 --to example.org/bundles/renamedbundle:v2.0.0
Копирование бандла в другой репозиторий
Для удобного копирования бандла в другой репозиторий имеется команда werf bundle copy . Кроме непосредственного копирования чарта и связанных с ним образов эта команда также обновит сохранённые в чарте Values, указывающие на путь к образам.
werf bundle copy --from example.org/bundles/mybundle:v1.0.0 --to other.example.org/bundles/mybundle:v1.0.0
Экспорт бандла из container registry в архив
После публикации бандл может быть экспортирован из репозитория в локальный архив для дальнейшей дистрибуции иными способами с помощью команды werf bundle copy , например:
werf bundle copy --from example.org/bundles/mybundle:v1.0.0 --to archive:archive.tar.gz
Импорт бандла из архива в репозиторий
Экспортированный в архив бандл можно снова импортировать в тот же или другой OCI-репозиторий командой werf bundle copy , например:
werf bundle copy --from archive:archive.tar.gz --to other.example.org/bundles/mybundle:v1.0.0
После этого вновь опубликованный бандл (чарт и его образы) снова можно использовать привычными способами.
Container registries, поддерживающие публикацию бандлов
Для публикации бандлов требуется container registry, поддерживающий спецификацию OCI (Open Container Initiative). Список наиболее популярных container registries, совместимость с которыми была проверена:
| Container registry | Поддерживает публикацию бандлов |
|---|---|
| AWS ECR | + |
| Azure CR | + |
| Docker Hub | + |
| GCR | + |
| GitHub Packages | + |
| GitLab Registry | + |
| Harbor | + |
| JFrog Artifactory | + |
| Yandex container registry | + |
| Nexus | + |
| Quay | — |