介紹
如果想要熟練使用 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
git如何做到分支互不影響
按照之前的理解,在當前 commit 上,會有乙個指標依附它,這個指標就是 testing 分支指標。
我們知道在我們開發中,如果建立了分支,就意味著互不影響,按照上面說的, 輕鬆建立了分支。
paste_image.png
git如何辨別我們工作的分支
既然只要新建了分支,我們的開發就和其他分支互不影響了,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鼓勵頻繁的使用分支。
待解決的問題?
所謂校驗和檔案是什麼?是乙個獨一無二的字串?為什麼又說它是指標呢?這個指標是根據什麼生成的?既然它指向commit檔案,那麼是不是根據commit檔案計算出的呢,commit物件之間是相連的,那麼如果通過commit檔案計算出的,那麼應該說的通。
所謂合併,到底是做了什麼,開啟了乙個新分支?貌似並沒有,因為開發過程只有乙個master,不會因為合併不斷的建立新分支。
合併之後會有一次commit,此時的commit物件就有兩個父物件了,好奇的commit歷史裡面在合併之前只有master物件?還是裡面亂亂的,根據時間會出現很多分支的commit物件,哈哈,等本少年去試試,不過前者的可能性貌似大些吧。
git上傳分支的原理 git(五)之分支差異對比
一 前言 git分支之間的差異提交對比,可以讓我們更清晰的認識到兩個分支之間的差異,比如在合併完分支後,對比一下分支是否沒有差異來確定合併完成 在開發完成之後,執行分支差異對比來看需要有多少個合併提交等等。二 正文 其中使用git log去查詢對比兩個分支提交的差集,可以看兩個分支的差異,以及在合併...
Git學習小記之分支原理
如果想要熟練使用 git,沒有分支理念是絕對行不通的,在用 git 管理專案的時候,經常需要使用 commit 這個命令,那麼這個 commit 到底是指什麼呢?按照官方的解釋,這應該成為乙個物件,它包含著乙個指向暫存內容 被add的檔案 快照的指標,包含本次提交的附屬資訊,比如說作者等等,指向父 ...
git 分支原理介紹
git的工作原理 git版本控制是通過儲存不同時間點的快照實現的。git在提交操作時,git會儲存乙個提交物件,該提交物件中會包含 git的分支,其實本質上是指向提交物件的可變指標。由於建立分支的高效性,所以,git鼓勵開發人員建立分支!首先在建立git專案的時候,缺省會建立master分支!這個m...