如果想要熟練使用 git,沒有分支理念是絕對行不通的,在用 git 管理專案的時候,經常需要使用 commit 這個命令,那麼這個 commit 到底是指什麼呢?
按照官方的解釋,這應該成為乙個物件,它包含著乙個指向暫存內容(被add的檔案)快照的指標,包含本次提交的附屬資訊,比如說作者等等,指向父 commit 物件(如果被 merge 而成,可能有多個父 commit 物件)的指標。
舉下面這個例子來分析:
git add readme test.rb license
git commit -m 'initial commit of my project'
add
:暫存操作會對檔案計算校驗和(sha-1雜湊字串),然後與當前版本的檔案快照(用blob
物件儲存)一起存入到暫存區域中。
校驗和(英語:checksum)是冗餘校驗的一種形式。 它是通過錯誤檢測方法,對經過空間(如通訊)或者時間(如計算機儲存)傳送的資料的完整性進行檢查的一種簡單方法。
commit
:正式建立提交物件前:git 先計算出每乙個子目錄的校驗和,然後在 git 倉庫中,將這些目錄儲存為樹物件。
建立提交物件的過程主要日下:
攜帶相關提交資訊,包含乙個指向該樹的指標,這樣就代表如果將來需要,可以重現此次快照內容。
來看看現在倉庫中有什麼:
乙個表示檔案快照內容的blob
物件,乙個記錄著目錄樹內容,以及其中各個檔案具體對應哪個blob
物件的索引tree
物件。以及乙個包含著指向索引tree
物件,以及其他提交資訊元資料的commit
物件。
如圖:首次提交物件及其樹結構
如果我們做一些修改,再次進行提交,此時就開始發生變化,commit
提交物件會再多包含乙個指向上次commit
提交物件的指標。
如官方圖:
paste_image.png
有了上面的準備知識,我們可以開始學習分支了。先回顧現在的提交模型:
每次提交都會生成乙個新的commit
物件,還有乙個指向上次提交,也就是父物件的指標。
git 中的分支的本質上就僅僅是指向commit
物件的指標,如果 git 分支這個指標指向某次commit
,它就擁有了此次commit
物件,這意味著很多。
git中預設的都會有乙個分支,這個分支叫做master
,若干次提交之後,實際上有乙個最新的commit
物件,以及指向這個物件的master
分支,伴隨著每次提交,master
物件要做的就是不斷指向新commit
物件。
現在有些清晰了,其實在 git 中建立分支,就是建立乙個指向某次commit
物件的可變指標,我們來新建乙個開發分支:
git branch testing
按照之前的理解,在當前commit
上,會有乙個指標依附它,這個指標就是testing
分支指標。
我們知道在我們開發中,如果建立了分支,就意味著互不影響,按照上面說的, 輕鬆建立了分支。
paste_image.png
既然只要新建了分支,我們的開發就和其他分支互不影響了,git 是如何分辨我們到底在哪個分支上工作呢?
其實答案比較簡單,git 包含著乙個名為head
的特別指標,在git中,它會指向你正在工作的本地分支指標上(將head
想象成當前分支指標的別名)。
上面使用git branch
建立了乙個分支,此時僅僅建立了乙個分支指標,head
指標未出現過移動,依然指向之前的master
。要切換head
指標的指向,使用切糕
命令。
git checkout testing
此時head
指向之前新建的testing
分支,但是master
分支依然指向checkout
時所在的那個commit
物件。這個的確太有意思了。。
所謂分支,從當前分支建立(預設是master
分支),使用切糕命令,本質上做的就是切換head
物件的指標的位置,並且把當前工作目錄上的檔案替換成分支所指向的快照內容。
此時如果進行一次commit
,那麼最新的commit
物件指向上次的提交,分支指標指向本次commit
,head
指標又指向本次分支。
繼續再進行切換
git checkout master
此時就到了重點,head
指標指向master
分支,master
分支指標指向某次commit
,同時checkout
還會將當前工作目錄中的檔案替換成master
分支所指向的快照內容(實際上在切糕命令執行時,我們完全可以認為快照會不斷的改變,也由於此時指向的是快照內容,所以切糕之前未暫存的檔案是無法經過切換來恢復了)。
我們修改master
分支上面的檔案,並且建立提交。由於我們之前已經建立過一次分支,並且提交過一次,然後才回到master
分支開發的,就會造成這樣一種情況,這兩次分支雖然指向的commit
物件的父物件個數是相同的,但是他們在此時出現了分歧,從master
分支開始,他們有不同的流向了,此時也就開始出現分叉了,我們可以不斷的切換分支,等待合適的時機,將它們合併到一起。
如上所見,在各個分支中無拘無束的開發,不斷的切換,僅僅只需要branch
,切糕兩個命令即可。
所謂分支,就是乙個指向某個物件的指標,這個指標是乙個校驗和檔案(40 個字元長度 sha-1 字串),所以新建和銷毀指標是非常廉價的事情,也就解釋了為什麼切換起來那麼快,那麼方便了。git鼓勵頻繁的使用分支。
git上傳分支的原理 Git學習小記之分支原理
介紹 如果想要熟練使用 git,沒有分支理念是絕對行不通的,在用 git 管理專案的時候,經常需要使用 commit 這個命令,那麼這個 commit 到底是指什麼呢?按照官方的解釋,這應該成為乙個物件,它包含著乙個指向暫存內容 被add的檔案 快照的指標,包含本次提交的附屬資訊,比如說作者等等,指...
Git學習筆記之分支
這些內容只是git知識的冰山一角 1.檢視當前版本庫當中有哪些分支 git branch a 2.建立分支名為 version1.0的分支 git branch version2.o再次檢視有哪些分支。號為當前的分支 git branch a master version1.0 remotes or...
Git 學習之分支 (二)
筆記源於 在 git 中提交時,會儲存乙個提交 commit 物件,該物件包含乙個指向暫存內容快照的指標,包含本次提交的作者等相關附屬資訊,包含零個或多個指向該提交物件的父物件指標 首次提交是沒有直接祖先的,普通提交有乙個祖先,由兩個或多個分支合併產生的提交則有多個祖先。git commit新建個提...