git 的原理
每一個(gè) git 倉庫下面有 .git 文件夾先口,其中主要包括 index, objects, refs, HEAD, config, hook, logs 文件种吸,下面詳細(xì)介紹各個(gè)文件夾的作用蹲诀。
git 文件版本管理
git管理的每個(gè)文件夾(tree)和文件(blog)都有一個(gè)索引號(hào)胳挎,在文件未發(fā)生修改時(shí)塞椎,其索引號(hào)保持不變。索引使用 sha-1 加密,生成 40位 16進(jìn)制組成的字符串株搔。
? ? ? ? git 有一個(gè)瑞士軍刀,叫 git cat-file -p **纯蛾,** 為分支或者 commit 號(hào)纤房。輸出的結(jié)果是對(duì)應(yīng)倉庫的 tree 索引號(hào),以及它依賴的父版本號(hào)茅撞。
? ? ? ? 其中 tree 索引對(duì)應(yīng)著倉庫下文件夾和文件的索引號(hào)帆卓,每一個(gè)分支或者 commit 號(hào)同樣對(duì)應(yīng)著一個(gè) tree 索引,考慮到不同分支或不同 commit 版本間的文件夾或文件索引號(hào)可能相同米丘,所以文件快照+鏈接的方式剑令,可以將所有的歷史提交信息存儲(chǔ)下來的同時(shí),也不會(huì)占用太多存儲(chǔ)空間拄查。
index文件
git ls-files -s? # 查看當(dāng)前分支對(duì)應(yīng)的倉庫文件的索引號(hào)吁津。每次 git checkout 到別的分支時(shí),index 會(huì)動(dòng)態(tài)的檢出該分支對(duì)應(yīng)庫文件的索引號(hào)堕扶。
如果在當(dāng)前分支進(jìn)行了修改碍脏,并使用 git add 將修改加入到 index 區(qū),則 index 區(qū)對(duì)應(yīng)文件的索引號(hào)將發(fā)生變化稍算,此時(shí)進(jìn)行 commit 典尾,.git/objects 數(shù)據(jù)文件夾下將增加該文件一個(gè)新的索引號(hào),同時(shí)庫文件也生成一個(gè)新的 tree 索引號(hào)糊探,并綁定到當(dāng)前提交的 commit 版本號(hào)上钾埂。
上面說過使用 git cat-file -p ** 即可以查看該 commit 版本號(hào)對(duì)應(yīng)的庫 tree 索引號(hào)河闰。
objects
存儲(chǔ)所有的數(shù)據(jù)文件,同一個(gè)文件會(huì)因?yàn)樗饕?hào)不同而存儲(chǔ)多份快照褥紫,每一個(gè)commit 版本都會(huì)鏈接使用其中的一份姜性。這種文件快照+鏈接的方式為 git 存儲(chǔ)數(shù)據(jù)的方式。
當(dāng) git 回退到歷史版本時(shí)髓考,歷史版本對(duì)應(yīng)文件的索引依然存在于 objects 文件夾下部念,故你在離線模式下依然可以切換到歷史版本進(jìn)行查看文件,比對(duì)差異氨菇。
HEAD
指向當(dāng)前分支
refs
存儲(chǔ)簡單名字對(duì)應(yīng)到提交的 sha-1 的值儡炼,這個(gè)簡單名字也就是我們說的分支。這樣我們每次對(duì)分支做的操作查蓉,其實(shí)就是對(duì)對(duì)應(yīng)提交的 sha-1值做操作射赛。
config
config 文件記錄著當(dāng)前倉庫的配置,以及本地倉庫和遠(yuǎn)程倉庫的對(duì)應(yīng)關(guān)系奶是。
logs
logs 文件夾記錄著每個(gè)分支的提交歷史版本號(hào)。使用 git log 可以看到當(dāng)前分支的歷史提交信息竣灌。
git gc
將 objects 下的文件進(jìn)行打包聂沙,壓縮。同一文件在 objects 目錄下不再以快照的形式存儲(chǔ)初嘹,而是比對(duì)差異進(jìn)行存儲(chǔ)及汉。每次向遠(yuǎn)程倉庫 push 的時(shí)候,git 都會(huì)調(diào)用 git gc 進(jìn)行打包屯烦,而 git push 后屏幕輸出的信息也就是 git gc 的過程信息坷随。
總結(jié)
想要深入理解 git 的工作流程,還是要理解 git 的工作原理驻龟。