-
1. 起步
-
2. Git 基礎
-
3. Git 分支
-
4. 伺服器上的 Git
- 4.1 協定
- 4.2 在伺服器上取得 Git
- 4.3 產生您的 SSH 公開金鑰
- 4.4 設定伺服器
- 4.5 Git Daemon
- 4.6 智慧型 HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方託管選項
- 4.10 總結
-
5. 分散式 Git
-
A1. 附錄 A:其他環境中的 Git
- A1.1 圖形介面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 總結
-
A2. 附錄 B:將 Git 嵌入您的應用程式
-
A3. 附錄 C:Git 命令
7.12 Git 工具 - 打包
打包
雖然我們已經介紹了通過網路傳輸 Git 資料的常見方式(HTTP、SSH 等),但實際上還有一種不太常用但實際上可能非常有用的方法。
Git 能夠將其資料「打包」成單個檔案。這在各種情況下都很有用。也許您的網路中斷了,您想將變更發送給您的同事。也許您在異地工作,並且由於安全原因無法訪問本地網路。也許您的無線/乙太網路卡剛壞了。也許您目前無法訪問共享伺服器,您想通過電子郵件向某人發送更新,並且您不想通過 format-patch
傳輸 40 個提交。
這就是 git bundle
命令可以派上用場的地方。 bundle
命令會將通常使用 git push
命令通過網路推送的所有內容打包到一個二進位檔案中,您可以將該檔案通過電子郵件發送給某人或放入隨身碟,然後解壓縮到另一個儲存庫中。
讓我們看一個簡單的範例。假設您有一個包含兩個提交的儲存庫
$ git log
commit 9a466c572fe88b195efd356c3f2bbeccdb504102
Author: Scott Chacon <schacon@gmail.com>
Date: Wed Mar 10 07:34:10 2010 -0800
Second commit
commit b1ec3248f39900d2a406049d762aa68e9641be25
Author: Scott Chacon <schacon@gmail.com>
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
或包含的任何分支,否則它將不知道要檢出哪個分支。
現在假設您對它進行了三個提交,並想通過 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
首先,我們需要確定要包含在包中的提交範圍。與網路協定會為我們找出通過網路傳輸的最小資料集不同,我們必須手動找出。現在,您可以執行相同的操作並打包整個儲存庫,這樣做雖然可行,但最好只打包差異部分,即我們剛剛在本地進行的三個提交。
為了做到這一點,您需要計算差異。如同我們在提交範圍中描述的,您可以用多種方式指定提交的範圍。要取得我們 master
分支中,但原始複製的分支中沒有的三個提交,我們可以像這樣使用 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
現在我們有了想要包含在 bundle 中的提交列表,讓我們將它們打包起來。我們使用 git bundle create
命令來完成,提供我們想要的 bundle 檔名,以及要包含在其中的提交範圍。
$ 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 時,她可以先檢查它包含的內容,然後再將其匯入她的儲存庫。第一個命令是 bundle verify
命令,它將確保該檔案實際上是一個有效的 Git bundle,並且您擁有所有必要的祖先來正確地重建它。
$ 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
如果打包者只建立最後兩個提交的 bundle,而不是全部三個提交,則原始儲存庫將無法匯入它,因為它缺少必要的歷史記錄。 verify
命令會像這樣顯示
$ git bundle verify ../commits-bad.bundle
error: Repository lacks these prerequisite commits:
error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 Third commit - second repo
但是,我們第一個 bundle 是有效的,所以我們可以從中獲取提交。如果您想查看 bundle 中有哪些可以匯入的分支,還有一個命令可以列出 head
$ git bundle list-heads ../commits.bundle
71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
verify
子命令也會告訴您 head。重點是要查看可以提取的內容,因此您可以使用 fetch
或 pull
命令從此 bundle 匯入提交。在這裡,我們將 bundle 的 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
對於共享或進行網路類型操作非常有用。