履歴の持ち出しに使うファイル
Git bundleは、Gitの履歴を1つのファイルへまとめる仕組みです。保存したファイルから新しいリポジトリを作れるため、ネットワークにつながずに履歴を別の端末へ渡せます。Git公式のgit-bundle資料には、保存とcloneによる復元の例があります。
ただし、編集中のファイルまで丸ごと保存するものではありません。ここではコミット済みの内容を復元し、未コミットの変更と未追跡ファイルが戻らないことも確かめます。既存の作業フォルダを使わず、専用の一時フォルダで実行してください。
以下はLinuxのBash向けのコマンドです。Git 2.28以降を前提とします。掲載手順の動作確認は2026年9月19日にWindows上のGit BashとGit 2.45.1.windows.1で実施しました。Linux環境そのものでは未検証です。
1. 保存する履歴と、保存されない変更を作る
新しいターミナルで次のコマンドを実行します。mktempが作ったフォルダ内にsourceを用意し、note.txtをコミットします。名前とメールアドレスは、この検証用リポジトリだけに設定する例示値です。
タグv1とブランチtopicを作った後、note.txtを書き換え、scratch.txtを追加します。末尾のstatusで「 M note.txt」と「?? scratch.txt」が表示されれば、未コミット変更と未追跡ファイルを用意できています。
trial=$(mktemp -d)
cd "$trial"
git init -b main source
git -C source config user.name 'Bundle Test'
git -C source config user.email 'bundle-test@example.invalid'
printf 'committed\n' > source/note.txt
git -C source add note.txt
git -C source commit -m 'Save note'
git -C source tag v1
git -C source branch topic
printf 'uncommitted\n' > source/note.txt
printf 'untracked\n' > source/scratch.txt
git -C source status --short2. bundleを作り、mainを指定して復元する
同じターミナルで続けます。--allは、そのリポジトリにある参照と、そこからたどれる履歴を保存する指定です。verifyはファイルの形式や必要な前提コミットを確認します。成功しても、作業中のファイルが含まれる証明にはならないため、続けて別フォルダへ復元します。
cloneには-b mainを付け、復元直後に開くブランチを指定します。この例のmainとtopicは同じコミットを指しており、省略すると元と同じブランチ名が選ばれるとは限りません。各コマンドがエラーになった場合は、その段階で止めて表示内容を確認してください。
git -C source bundle create ../backup.bundle --all
git -C source bundle verify ../backup.bundle
git clone -b main backup.bundle restored3. コミットIDとファイル内容を照合する
次の4行で表示されるコミットIDを、main同士、v1同士で比べます。IDの文字列自体は実行ごとに変わりますが、それぞれ保存元と復元先で一致することを確かめます。note.txtの中身はcommittedに戻り、scratch.txtは復元先にありません。
今回の検証では、mainとv1のIDがそれぞれ一致しました。復元先のnote.txtはcommittedで、scratch.txtは存在しませんでした。保存元の未コミット変更と未追跡ファイルはそのまま残りました。
git -C source rev-parse main
git -C restored rev-parse main
git -C source rev-parse v1
git -C restored rev-parse v1
cat restored/note.txt
if test -e restored/scratch.txt; then
printf 'scratch.txt exists\n'
else
printf 'scratch.txt absent\n'
fi表は横にスクロールできます →
| 保存元にあるもの | 今回の復元結果 |
|---|---|
| mainのコミットとタグv1 | 保存元と復元先のIDが一致 |
| note.txtのコミット済み内容 | committedを復元 |
| note.txtの未コミット変更 | uncommittedは復元されない |
| 未追跡のscratch.txt | 復元先には存在しない |
4. topicを開き、originの行き先を確かめる
--allで保存しても、通常のcloneが全ブランチをローカルブランチとして作るわけではありません。今回のclone直後はmainがローカルブランチ、topicはorigin/topicとして存在しました。branch -aで確認し、topicを開くには次のようにローカルブランチを作ります。Git公式のgit-clone資料でも、元のブランチに対応するリモート追跡ブランチを作る動作が説明されています。
topicを作った後、2行のrev-parseが表示するコミットIDが保存元と復元先で一致することを確認します。
remote -vに出るoriginは、以前使っていたGitホスティングのURLではなくbackup.bundleのパスです。このファイルへpushして更新することはできません。実際の開発を再開する場合は、接続すべきリモートURLを別に確認する必要があります。
git -C restored branch -a
git -C restored switch -c topic --track origin/topic
git -C source rev-parse topic
git -C restored rev-parse topic
git -C restored remote -v実際のリポジトリを保存するときに別途必要なもの
この手順は、浅いcloneや部分cloneではない、小さな通常のリポジトリで試しています。実際の保存前にはgit statusで未コミット変更を調べ、残したい作業ファイルを別に保存してください。ローカルの設定やhooksも、bundleからは復元されません。
Git LFSを使う場合、Gitの中には大きなファイルの実体に代わるポインターが入ります。Git LFS公式の説明にあるように実体は別に保管されるため、bundleだけで実体まで保存したとは扱えません。submoduleも独立した履歴を持つ別のリポジトリなので、それぞれの保存と復元が必要です。この2種類の復元は今回の検証には含めていません。
検証後も、端末故障への備えにはbundleを別の保存先へコピーする作業が必要です。同じディスクに置いただけでは、ディスク全体を失う場合に対応できません。元のリポジトリは、移した保存先からの復元確認が終わるまで残してください。