這一章會詳細講解Git如何物理存儲各對象。
所有的對象都以SHA值為索引用gzip格式壓縮存儲, 每個對象都包含了對象類型, 大小和內容.
Git中存在兩種對象 - 松散對象(loose object)和打包對象(packed object)。
## 松散對象
松散對象是一種比較簡單格式. 它就是磁盤上的一個存儲壓縮數據的文件. 每一個對象都被寫入一個單獨文件中.
如果你對象的SHA值是`ab04d884140f7b0cf8bbf86d6883869f16a46f65`, 那么對應的文件會被存儲在:
~~~
GIT_DIR/objects/ab/04d884140f7b0cf8bbf86d6883869f16a46f65
~~~
Git使用SHA值的前兩個字符作為子目錄名字, 所以一個目錄中永遠不會包含過多的對象. 文件名則是余下的38個字符.
可以用下面的Ruby代碼說明對象數據是如何存儲的:
~~~
def put_raw_object(content, type)
size = content.length.to_s
header = "#{type} #{size}\0" # type(space)size(null byte)
store = header + content
sha1 = Digest::SHA1.hexdigest(store)
path = @git_dir + '/' + sha1[0...2] + '/' + sha1[2..40]
if !File.exists?(path)
content = Zlib::Deflate.deflate(store)
FileUtils.mkdir_p(@directory+'/'+sha1[0...2])
File.open(path, 'w') do |f|
f.write content
end
end
return sha1
end
~~~
## 打包對象
另外一種對象存儲方式是使用打包文件(packfile). 由于Git把每個文件的每個版本都作為一個單獨的對象, 它的效率可能會十分的低. 設想一下在一個數千行的文件中改動一行, Git會把修改后的文件整個存儲下來, 很浪費空間。
Git使用打包文件(packfile)去節省空間. 在這個格式中, Git只會保存第二個文件中改變了的部分, 然后用一個指針指向相似的那個文件(譯注: 即第一個文件)。
對象通常是以松散格式寫到磁盤上, 因為這個格式的訪問代價比較低. 然后, 你最終會需要把對象存放到打包格式中去節省磁盤空間 - 這個工作可以通過[git gc](http://www.kernel.org/pub/software/scm/git/docs/git-gc.html)來完成. 它使用一個相當復雜的啟發式算法去決定哪些文件是最相似的, 然后基于此分析去計算差異. 可以存在多個打包文件, 在必要情況下, 它們可被解包([git unpack-objects](http://www.kernel.org/pub/software/scm/git/docs/git-unpack-objects.html))成為松散對象或者重新打包([git repack](http://www.kernel.org/pub/software/scm/git/docs/git-repack.html)).
Git會為每一個打包文件創建一個較小的索引文件. 索引文件中包含了對象在打包文件中的偏移, 以便于通過SHA值來快速找到特定的對象。
打包文件的實現細節會在稍后的"打包文件"(Packfile)一章中講述。
- 1. 介紹
- 歡迎使用Git
- GIT對象模型
- Git目錄 與 工作目錄
- Git索引
- 2. 第一步
- 安裝Git
- 安裝與初始化
- 3. 基本用法
- 獲得一個Git倉庫
- 正常的工作流程
- 分支與合并@基礎
- 查看歷史 -Git日志
- 比較提交 - Git Diff
- 分布式的工作流程
- Git標簽
- 4. 中級技能
- 忽略某些文件
- rebase
- 交互式rebase
- 交互式添加
- 儲藏
- Git樹名
- 追蹤分支
- 使用Git Grep進行搜索
- Git的撤消操作 - 重置, 簽出 和 撤消
- 維護Git
- 建立一個公共倉庫
- 建立一個私有倉庫
- 5. 高級技能
- 創建新的空分支
- 修改你的歷史
- 高級分支與合并
- 查找問題的利器 - Git Bisect
- 查找問題的利器 - Git Blame
- Git和Email
- 定制Git
- Git Hooks
- 找回丟失的對象
- 子模塊
- 6. Git生態體系
- Git 與之 Windows
- 使用Git進行系統部署
- 與 Subversion 集成
- 從其他代碼管理工具遷移到Git
- 圖形化的Git
- Git倉庫托管
- Git的其它用法
- Git的腳本支持
- Git 與編輯器
- 7. 原理解析
- Git是如何存儲對象的
- 查看Git對象
- Git引用
- Git索引
- 打包文件
- 更底層的Git
- 傳輸協議
- 術語表