Git Bundle:オフライン環境でリポジトリをパッケージ化する究極のテクニック

Git tutorial - IT technology blog
Git tutorial - IT technology blog

背景:インターネットが「贅沢品」だった頃

ある大手銀行のプロジェクトに携わっていた際、すべてのサーバーが完全に隔離された(エアギャップ)環境に設置されていました。データの安全性を確保するため、インターネットも外部ネットワークへの接続も一切ありません。そうなると、GitHubでおなじみの git pushgit pull といったコマンドは全く役に立ちません。そこで直面した課題が、「コミット履歴、ブランチ、タグをすべて保持したまま、どうやってコードをサーバーに持ち込むか?」ということでした。

多くの人は、プロジェクトディレクトリ全体を .zip ファイルに圧縮してUSBメモリでコピーする方法を選びがちです。しかし、この方法は大きなリスクを伴います。.git ディレクトリには、数万個もの小さなファイルが含まれていることがあります。コピー中にファイルが一つでも破損すれば、リポジトリ全体が壊れてしまいます。また、圧縮ファイルは node_modules や一時的なビルドファイルまで含んでしまい、非常に重くなりがちです。

よりプロフェッショナルな解決策が git bundle です。これはリポジトリを単一のバイナリファイルにパッケージ化し、「持ち運び可能なリポジトリ」として機能させます。このファイルを使って、本物のサーバーのように git clonegit pull を行うことができます。

なぜ git bundle が手動の圧縮よりも優れているのか?

  • エラーチェック: パッケージ化の際、Gitが整合性を自動的にチェックします。ファイルが破損していれば、展開時に即座にエラーが通知されます。
  • 軽量化: Bundleには必要なコミットとオブジェクトのみが含まれます。500MBのリポジトリが、bundle後は150MBまで削減されることもあります。
  • 柔軟な更新: プロジェクト全体を送り直す代わりに、最新のコミットだけをパッケージ化して送ることができます。

パッケージ化前の準備

git bundle コマンドは、標準のGitインストールに含まれています。サードパーティ製のツールを追加でインストールする必要はありません。開始する前に、リポジトリをクリーンアップして、bundleファイルのサイズを最適化しましょう。

私はよく git gc (Garbage Collection) コマンドを実行します。このコマンドはGitオブジェクトを再整理し、データをより効率的に圧縮します。

# リポジトリを最適化してbundleファイルのサイズを削減する
git gc --prune=now --aggressive

実際のところ、このステップを踏むことで、コミット履歴が膨大な長年のプロジェクトではファイルサイズを20〜30%削減できます。

実践的な使い方

1. フルバックアップ(全体)のBundleファイル作成

ブランチからタグまで、すべてを一つのファイルに詰め込むには、以下のコマンドを使用します:

# リポジトリ全体をパッケージ化する
git bundle create my-project.bundle --all

サイズを抑えるために、特定のブランチだけを同僚に送りたい場合は、以下のようにします:

# mainブランチのみをパッケージ化する
git bundle create main-only.bundle main

2. Bundleファイルからコードを復元する

移動先のコンピュータでは、bundleファイルをGitHubのURLのように扱います。クローンは非常に簡単です:

# パッケージ化されたファイルからプロジェクトをクローンする
git clone my-project.bundle my-new-folder

クローン後、Gitはデフォルトのリモート名 origin をそのbundleファイルを指すように設定します。bundleファイルを削除したり移動したりすると、その後の fetch コマンドなどは動作しなくなります。

3. 差分(新しい変更)のみを送る

これが最も価値のある機能です。例えば、先週1GBのbundleファイルを送ったとします。今週は10コミット(約200KB)だけ追加しました。再度1GB送り直すのは、非常に時間の無駄です。

古いバージョンから現在までのコミットを含む「パッチ」用のbundleを作成しましょう:

# タグ v1.0 から現在までのbundleを作成する
git bundle create update-v1.1.bundle v1.0..main

受け取り側は、この数百KBのファイルをダウンロードして pull を実行するだけです:

git pull update-v1.1.bundle main

ファイルの安全性を確認する

チェックせずにすぐにファイルを送ってはいけません。バイナリ形式なので、テキストエディタで内容を確認することはできません。

コピー中にファイルが壊れていないか確認するには、verify コマンドを使用します:

git bundle verify my-project.bundle

bundleの中にどのようなブランチが含まれているかを確認するには、list-heads を使用します:

git bundle list-heads my-project.bundle

実体験から得た教訓

私は以前、ネットワークのない顧客先オフィスで働く8人のチームを管理していました。私たちのフローは非常にシンプルでした。一日の終わりに、一人がチーム全員のコードを daily_sync.bundle ファイルにまとめます。このファイルをUSBメモリにコピーして持ち帰り、自宅から会社のGitLabにプッシュしていました。この方法により、データを失うことなく、コミット履歴を100%保持することができました。

小さな注意点:Bundleには .git/config の設定は保存されません。新しいマシンにクローンした後は、その後のコミットが正しく記録されるよう、改めて user.nameuser.email を設定する必要があります。

git bundle の使用は、単なる緊急避難的な手段ではありません。重要なプロジェクトのための非常に安全なバックアップ手法でもあります。

Share: