Git之深入解析在沒有合適的網絡或者可共享倉庫情況下的git bundle打包操作
了解了管理或者維護 Git 倉庫、實現代碼控制所需的大多數日常命令和工作流程,嘗試跟了蹤和提交文件的基本操作,并且掌握了暫存區和輕量級地分支及合并的威力。如果想進一步對 Git 深入學習,可以學習一些 Git 更加強大的功能,這些功能可能并不會在日常操作中使用,但在某些時候可能還是會起到一定的關鍵性作用。
如果還不清楚 Git 的基礎使用流程、分支的管理、托管服務器的技術以及分布式工作流程等相關的技術和能力,請參考博客:
Git之深入解析Git的安裝流程與初次運行Git前的環境配置;
Git之深入解析本地倉庫的基本操作·倉庫的獲取更新和提交歷史的查看撤銷以及標簽別名的使用;
Git之深入解析Git的殺手級特性·分支管理與變基的開發工作流以及遠程分支的跟蹤;
Git之深入解析如何運行自己的Git倉庫托管服務器;
Git之深入解析如何使用Git的分布式工作流程與如何管理多人開發貢獻的項目。
雖然已經了解了網絡傳輸 Git 數據的常用方法(如 HTTP,SSH 等),但還有另外一種不太常見卻又十分有用的方式,Git 可以將它的數據“打包”到一個文件中。
來看看一個簡單的例子,假設有一個包含兩個提交的倉庫:
$ git log commit 9a466c572fe88b195efd356c3f2bbeccdb504102 Author: Scott Chacon
1
2
3
4
5
6
7
8
9
10
11
12
如果想把這個倉庫發送給其他人但沒有其他倉庫的權限,或者就是懶得新建一個倉庫,就可以用 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)
1
2
3
4
5
6
然后就會有一個名為 repo.bundle 的文件,該文件包含了所有重建該倉庫 master 分支所需的數據。在使用 bundle 命令時,需要列出所有希望打包的引用或者提交的區間,如果希望這個倉庫可以在別處被克隆,應該像例子中那樣增加一個 HEAD 引用。我們可以將這個 repo.bundle 文件通過郵件或者U盤傳給別人。
另一方面,假設別人傳給我們一個 repo.bundle 文件并希望在這個項目上工作,可以從這個二進制文件中克隆出一個目錄,就像從一個 URL 克隆一樣:
$ git clone repo.bundle repo Cloning into 'repo'... ... $ cd repo $ git log --oneline 9a466c5 second commit b1ec324 first commit
1
2
3
4
5
6
7
如果在打包時沒有包含 HEAD 引用,還需要在命令后指定一個 -b master 或者其他被引入的分支,否則 Git 不知道應該檢出哪一個分支。
現在假設提交了 3 個修訂,并且要用郵件或者U盤將新的提交放在一個包里傳回去:
$ git log --oneline 71b84da last commit - second repo c99cf5b fourth commit - second repo 7011d3d third commit - second repo 9a466c5 second commit b1ec324 first commit
1
2
3
4
5
6
首先我們需要確認我們希望被打包的提交區間,和網絡協議不太一樣,網絡協議會自動計算出所需傳輸的最小數據集,而我們需要手動計算。當然可以像上面那樣將整個倉庫打包,但最好僅僅打包變更的部分,就是我們剛剛在本地做的 3 個提交。
為了實現這個目標,我們需要計算出差別,有很多種方式去指明一個提交區間,我們可以使用 “origin/master…master”或者“master ^origin/master”之類的方法來獲取那 3 個在 master 分支而不在原始倉庫中的提交。可以用 log 命令來測試:
$ git log --oneline master ^origin/master 71b84da last commit - second repo c99cf5b fourth commit - second repo 7011d3d third commit - second repo
1
2
3
4
這樣就獲取到我們希望被打包的提交列表,讓我們將這些提交打包,可以用 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)
1
2
3
4
5
6
當她拿到這個包時,她可以在導入到倉庫之前查看這個包里包含了什么內容,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
1
2
3
4
5
6
如果打包工具僅僅把最后兩個提交打包,而不是三個,原始的倉庫是無法導入這個包的, 因為這個包缺失了必要的提交記錄。這時候 verify 的輸出類似:
$ git bundle verify ../commits-bad.bundle error: Repository lacks these prerequisite commits: error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 third commit - second repo
1
2
3
而我們的第一個包是合法的,所以可以從這個包里提取出提交。如果想查看這邊包里可以導入哪些分支,同樣有一個命令可以列出這些頂端:
$ git bundle list-heads ../commits.bundle 71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
1
2
verify 子命令同樣可以知道哪些頂端,該功能的目的是查看哪些是可以被拉入的,所以可以使用 fetch 或者 pull 命令從包中導入提交。這里我們要從包中取出 master 分支到我們倉庫中的 other-master 分支:
$ git fetch ../commits.bundle master:other-master From ../commits.bundle * [new branch] master -> other-master
1
2
3
可以看到已經將提交導入到 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
1
2
3
4
5
6
7
8
因此,當在沒有合適的網絡或者可共享倉庫的情況下,git bundle 很適合用于共享或者網絡類型的操作。
Git 網絡
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。