Git 分支(一)簡介&創建分支


理解Git暫存區

  文件.git/index是一個包含文件索引的目錄樹,像是一個虛擬的工作區。在這個虛擬工作區的目錄樹中,記錄了文件名和文件的狀態信息。以便快速檢測文件的變化。                                                              索引中還包含所有Blob類型的SHA-1標識符。文件的內容沒有存儲在其中, 而是保存在Git對象庫.git/objects目錄中,文件索引建立了文件和對象庫中對象實體之間的對應,                                                       如圖,展示了工作區、版本庫中的暫存區和版本庫之間的關系。

 - 圖中左側為工作區,右側為版本庫。在版本庫中標記為index的區域是暫存區,標記為master的是master分支代表的目錄樹。

 - HEAD實際是指向master分支的一個“游標”,所以圖示的命令中出現的HEAD的地方可以用master來替代。

 - objects標志的區域為Git的對象庫,實際位於.git/objects目錄下。

 - 工作區修改(或新增)文件執行git add命令時,暫存區的目錄樹將被更新,同時工作區修改(或新增)的文件內容會被寫入到對象庫中的一個新的對象中,而該對象的ID被記錄在暫存區的索引文件中。

 - 執行提交操作(git commit)時,暫存區的目錄樹會寫到版本庫(對象庫)中,master分支會做相應的更新,即master最新指向的目錄樹就是提交時原暫存區的目錄樹。

 - 執行git  reset HEAD命令時,暫存區的目錄樹會被重寫,會被master分支指向的目錄樹替換,但是工作區不受影響。

 - 執行 git rm --cached <file>命令時,會直接從暫存區刪除文件,工作區不做改變。

 - 執行 git checkout. 或 git checkout -- <file>命令時,會用暫存區全部的文件或指定的文件替換工作區的文件。這個操作很危險,會清除工作區中未添加到暫存區的改動。

 - 執行 git checkout HEAD ,或 git  checkout HEAD <file> 命令時,會用HEAD指向的master分支中的全部或部分文件替換暫存區和工作區中的文件,這個命令也是極具危險性的,因為不但會清除工作             區中未提交的改動,也會清楚暫存區中為提交的改動。

分支

  Git 在進行提交操作時,會創建一個提交對象(commit object)。該提交對象會包含一個指向提交內容快照的指針、作者的姓名和郵箱、提交時輸入的信息以及
指向它的父對象的指針。首次提交產生的提交對象沒有父對象,普通提交操作產生的提交對象有一個父對象,而由多個分支合並產生的提交對象有多個父對象。

 

  假設一個工作目錄,包含了三個將要被暫存和提交的文件。 暫存操作會為每一個文件計算校驗和(使用我們在 起步 中提到的 SHA-1 哈希算法),
然后把當前版本的文件快照保存到Git 倉庫中(objects,Git 使用 blob 對象來保存它們),將校驗和加入到暫存區域等待提交: 

  當使用 git commit 進行提交操作時,Git 會先計算每一個子目錄(本例中只有項目根目錄)的校驗和,然后在Git 倉庫中這些校驗和保存為樹對象。
Git 會創建一個提交對象,它除了包含上面提到的那些信息外,還包含指向這個樹對象(項目根目錄)的指針。如此一來,Git 就可以在需要的時候重現此次保存的快照。

現在,Git 倉庫中有五個對象:三個 blob 對象(保存着文件快照)、一個樹對象(記錄着目錄結構和 blob 對象索引)以及一個提交對象(包含着指向前述樹對象的指針                                                              和所有提交信息)。

 Git 的分支,其實本質上僅僅是指向提交對象的可變指針。 Git 的默認分支名字是 master。 在多次提交操作之后,你其實已經有一個指向最后
那個提交對象的 master 分支。 它會在每次的提交操作中自動向前移動。

分支創建

  $ git branch testing         #創建一個 testing 分支 
  

創建Testing分支會在當前所在的提交對象上創建一個指針。

 可以簡單地使用 git log 命令查看各個分支當前所指的對象。 提供這一功能的參數是 --decorate

正如你所見,當前 “master” 和 “testing” 分支均指向校驗和以 f30ab 開頭的提交對象。

 

分支切換
  要切換到一個已存在的分支:  
            

這樣 HEAD 就指向 testing 分支了。

現在不妨再提交一次:

  

如圖所示, testing 分支向前移動了,但是 master 分支卻沒有,它仍然指向運行 git checkout 時所指的對象。 這就有意思了,
現在我們切換回 master 分支看看:

  

這條命令做了兩件事。 一是使 HEAD 指回 master 分支,二是將工作目錄恢復成 master 分支所指向的快照內容。

我們不妨再稍微做些修改並提交:
   

你可以簡單地使用 git log 命令查看分支歷史。 運行 git log --oneline --decorate --graph--all ,它會輸出你的提交歷史、各個分支的指向以及項目的分支分支情況。
 

 

      由於 Git 的分支實質上僅是包含所指對象校驗和(長度為 40 的 SHA-1 值字符串)的文件,所以它的創建和銷毀都異常高效。創建一個新分支就相當於往一個文件
 中寫入 41 個字節(40 個字符和 1 個換行符),如此的簡單能不快嗎?

       這與過去大多數版本控制系統形成了鮮明的對比,它們在創建分支時,將所有的項目文件都復制一遍,並保存到一個特定的目錄。 完成這樣繁瑣的過程通常需要
好幾秒鍾,有時甚至需要好幾分鍾。所需時間的長短,完全取決於項目的規模。而在 Git 中,任何規模的項目都能在瞬間創建新分支。 同時,由於每次提交都會記錄父對象,
所以尋找恰當的合並基礎(譯注:即共同祖先)也是同樣的簡單和高效。 這些高效的特性使得 Git 鼓勵開發人員頻繁地創建和使用分支。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM