English ▾ 主題 ▾ 最新版本 ▾ git-bundle 最後更新於 2.48.0

名稱

git-bundle - 以封存檔移動物件與參考 (refs)

概要

git bundle create [-q | --quiet | --progress]
		    [--version=<version>] <file> <git-rev-list-args>
git bundle verify [-q | --quiet] <file>
git bundle list-heads <file> [<refname>…​]
git bundle unbundle [--progress] <file> [<refname>…​]

描述

建立、解開與操作「套件 (bundle)」檔案。套件用於在無法透過網路連線存取「伺服器」的情況下,「離線」傳輸 Git 物件。

它們可用於建立儲存庫的增量備份與完整備份(請參閱「範例」中的「完整備份」範例),並將一個儲存庫中參考的狀態中繼傳輸至另一個儲存庫(請參閱第二個範例)。

透過 ssh://https:// 等協定進行抓取或「讀取」的 Git 指令,同樣可以對套件檔案進行操作。您可以從套件 git-clone[1] 出一個新儲存庫,使用 git-fetch[1] 從套件抓取內容,並使用 git-ls-remote[1] 列出其中包含的參考。目前沒有對應的「寫入」支援,亦即不支援將 git push 推送到套件中。

套件格式

套件是 .pack 檔案(請參閱 git-pack-objects[1]),並帶有一個標頭,標明套件中包含哪些參考。

如同封存檔格式本身,套件可以是自包含的,也可以透過排除某些物件來建立。請參閱下方的「物件先決條件」章節。

使用修訂版本排除所建立的套件是透過對 git-pack-objects[1] 使用 --thin 選項建立的「精簡封裝 (thin packs)」,並透過對 git-index-pack[1] 使用 --fix-thin 選項來解開。

使用修訂版本排除時,沒有建立「完整封裝 (thick pack)」的選項,使用者無需擔心兩者的區別。透過使用「精簡封裝」,利用排除建立的套件體積會更小。這裡僅將其「精簡」的特性視為一種技術細節,並作為參閱其他文件的參考。

請參閱 gitformat-bundle[5] 以獲取更多詳細資訊,並參閱 gitformat-pack[5] 中關於「精簡封裝」的討論以進一步了解。

選項

create [選項] <檔案> <git-rev-list-參數>

用於建立名為 檔案 的套件。這需要 <git-rev-list-參數> 來定義套件內容。選項 包含 git bundle create 子指令特有的選項。若 檔案-,套件將被寫入至標準輸出 (stdout)。

verify <檔案>

用於檢查套件檔案是否有效,以及是否能順利套用到當前儲存庫。這包括檢查套件格式本身,以及檢查先決條件的提交 (commits) 是否存在,且在當前儲存庫中完全連結。接著,git bundle 會列出缺少的提交(若有的話)。最後,會列出其他功能的資訊,例如「物件過濾器 (object filter)」。詳細資訊請參閱 gitformat-bundle[5] 中的「功能 (Capabilities)」。成功時結束代碼為零,若套件檔案無效則為非零。若 檔案-,則套件會從標準輸入 (stdin) 讀取。

list-heads <檔案>

列出套件中定義的參考。如果後面接著參考列表,則僅列出符合該列表的參考。若 檔案-,則從標準輸入讀取。

unbundle <檔案>

將套件中的物件傳遞給 git index-pack 以儲存至儲存庫中,然後列印所有定義的參考名稱。若給定了參考列表,則僅列印符合列表的參考。此指令屬於底層 plumbing 指令,預計僅由 git fetch 呼叫。若 檔案-,則從標準輸入讀取。

<git-rev-list-參數>

一組可由 git rev-parsegit rev-list 接受的參數(包含具名參考,請參閱下方的「指定參考」),用於指定要傳輸的特定物件與參考。例如,master~10..master 會導致當前的 master 參考與自其第 10 個祖先提交以來的所有物件被封裝在一起。封裝的參考與物件數量沒有明確限制。

[<參考名稱>…​]

用於限制報告可用參考的參考列表。這主要用於 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: Refusing to create empty bundle.
$ git bundle create master-yesterday.bundle master~10..master~5
fatal: Refusing to create empty bundle.

物件先決條件

建立套件時,可以建立一個自包含的套件(可在沒有共同歷史的儲存庫中解開),也可以提供負向修訂版本來排除歷史早期階段所需的物件。

將類似 new 的修訂版本輸入給 git bundle create,將會建立一個包含所有可從修訂版本 new 到達之物件的套件檔案。該套件可以在任何儲存庫中解開,以取得通往修訂版本 new 的完整歷史。

$ git bundle create full.bundle new

類似 old..new 的修訂範圍將產生一個套件檔案,該檔案需要修訂版本 old(以及任何可從其到達的物件)存在,套件才能被「解開」。

$ git bundle create full.bundle old..new

沒有任何先決條件的自包含套件可以被解壓縮到任何地方,即使是空的儲存庫,或者作為複製 (clone) 的來源(即 new,而非 old..new)。

採取謹慎態度是沒問題的,即便這會導致套件檔案包含目標儲存庫中已有的物件,因為這些物件在目標儲存庫解開時會被忽略。

若您希望提供與直接從來源儲存庫進行複製所獲得的相同參考集,請對 <git-rev-list-參數> 使用 --branches --tags

git bundle verify 指令可用於檢查您的接收儲存庫是否擁有套件所需的先決條件提交。

範例

我們將討論兩種情況

  1. 對儲存庫進行完整備份

  2. 當兩台機器之間沒有直接連線時,將儲存庫的歷史記錄傳輸到另一台機器

首先,讓我們考慮對儲存庫進行完整備份。以下指令將對儲存庫進行完整備份,其含義是所有參考都會包含在套件中

$ git bundle create backup.bundle --all

但請再次注意,這僅針對參考,亦即您將僅包含這些參考以及可從這些參考到達的提交。您不會包含其他本機狀態,例如索引內容、工作樹、stash、各儲存庫設定、鉤子 (hooks) 等。

稍後您可以透過例如 git-clone[1] 來復原該儲存庫

$ git clone backup.bundle <new directory>

對於下一個範例,假設您想將機器 A 上的儲存庫 R1 的歷史記錄傳輸到機器 B 上的另一個儲存庫 R2。無論出於何種原因,不允許機器 A 和 B 之間進行直接連線,但我們可以透過某些機制(CD、電子郵件等)將資料從 A 移動到 B。我們想用 R1 中 master 分支上的開發成果來更新 R2。

為了引導此過程,您可以先建立一個沒有任何先決條件的套件。您可以使用標籤 (tag) 來記錄您上次處理到哪個提交,以便稍後能更輕鬆地使用增量套件更新另一個儲存庫

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

然後您將 file.bundle 傳輸到目標機器 B。因為此套件不需要任何現有物件即可解壓縮,所以您可以透過從其複製 (clone) 來在機器 B 上建立一個新儲存庫

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

這將在結果儲存庫中定義一個名為 "origin" 的遠端,讓您可以從該套件進行抓取 (fetch) 和提取 (pull)。R2 中的 $GIT_DIR/config 檔案將會有類似這樣的項目

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

若要更新得到的 mine.git 儲存庫,您可以在將存放於 /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,並從中進行提取。

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

這將列出您必須擁有的提交才能從該套件解壓縮,如果您沒有這些提交,它將會回報錯誤。

從接收儲存庫的角度來看,套件就像是一個普通的儲存庫,可以從中抓取或提取。例如,您可以在抓取時對映參考

$ git fetch mybundle master:localRef

您也可以查看它提供了哪些參考

$ git ls-remote mybundle

討論

進行儲存庫完整備份的一種簡易方法是使用類似 cp -r <儲存庫> <目的地> 的指令。這是不被建議的,因為在複製操作期間,儲存庫可能會被寫入。進而導致 <目的地> 中的某些檔案可能會損毀。

這就是為什麼建議使用 Git 工具進行儲存庫備份的原因,可以使用此指令或例如 git-clone[1]。但請記住,這些工具無法協助您備份除參考和提交之外的狀態。換句話說,它們無法協助您備份索引、工作樹、stash、各儲存庫設定、鉤子等內容。

請參閱 gitfaq[7] 的「TRANSFERS」一節,了解有關跨系統檔案同步相關問題的討論。

檔案格式

請參閱 gitformat-bundle[5]

GIT

git[1] 套件的一部分