看完這篇文章才對【GIT】有了大徹大悟的認識


git定義:版本管理工具

歷史:沒有git的時候,我們修改完一個文件,要先把文件拷貝一個副本到備份文件夾中,還要建個文檔來記錄當前文件的信息和操作記錄。當文件多的時候,人工操作起來將是個非常辛苦非常龐大的工作量。

如今:有了git幫我們管理這些副本,為我們節約了非常大的人力成本,讓我們的工作變得更加輕松。我們不要把git看得那么神秘,git的核心就是創建備份和恢復備份,但是衍生出一堆的新概念,這些抽象概念可以幫助我們快速的學會git,但是要很好的使用git,我們還需要GIT的一些底層原理。本文章是從文件的層面出發來重新理解GIT的工作原理和GIT命令的具體實現。

基礎理論知識:

1.文件系統:我們可以把硬盤理解成一本漢語詞典,詞典前面的目錄索引就是文件系統,能幫助我們快速找到文件內容的具體位置,通常我們也只會通過索引去找文件,windows中的我的電腦就是一個索引系統,索引里面沒有的文件我們就“找不到”。我們知道從操作系統刪除文件,其實只是刪除了索引,具體文件內容還是存在硬盤上的,雖然我們通過索引找不到,但是我們可以通過內容去查找(利用一些恢復工具)。

2.git倉庫:就是用來存放備份文件的地方,但是備份文件存入倉庫的時候會壓縮,這些壓縮的備份文件存放在.git/objects目錄中,直接打開是亂碼,而且為了節省空間,倉庫不會存放重復的文件,只有新增和修改過的文件才會存入git倉庫,刪除的時候並不會從倉庫移除文件,不然我們怎么恢復呢。

3.HEAD:git的版本日志或版本號,通過git log 我們可以看到很多的編號,我們通過修改head指針來切換版本,每個版本關聯一份快照,每個關照關聯一系列文件,就是“HEAD->快照->倉庫文件”這樣一個關系鏈,我們可以很輕松的通過移動HEAD指針來改變我們的工作區文件。

4.暫存區/緩沖區:暫存區並不存放文件內容,暫存區僅僅是一份處於編輯狀態的快照(索引文件),這份快照沒有編號。commit就是把暫存區保存到版本庫,並給版本日志新增一個編號(HEAD/版本號)指向這個快照副本。

5.git快照:我們知道git是通過快照來管理版本的,快照就是git的文件系統,就是我們說的漢語詞典的索引,每次commit就是創建一份快照,並給快照起一個編號,這個編號就是HEAD。

6.工作區:工作區就是除開.git目錄的其他東西。通過操作系統的文件索引來管理的內容。就是我們正常使用電腦的時候所看到,能編輯的內容。

7.分支:分支其實就是上面說到的版本日志,一個分支就是一個版本分組,每個分支記錄該分支上的所有HEAD,分支->HEAD->快照->倉庫文件”

同學們可以通過下面的圖片來理解以上幾個概念,下圖中的每個方塊都是存放在硬盤上的文件,git就是建立了這樣一個關系庫來管理版本的(途中的緩沖區就是暫存區)。

大家不要被上圖的復雜線條縮困擾,你只需要弄清HEAD就行了,我們移動HEAD指針其實就是通過HEAD編號找到快照,再通過快照找到這個HEAD的所有文件。

git命令的理解:

1、status

  1.1、對比暫存區跟工作區,對比結果主要存在3種情況:

    1.1.1、【刪】暫存區記錄的文件在工作區沒有,add的時候會從暫存區移除對應的文件索引,但並不影響git倉庫的內容。

    1.1.2、【增】工作區已有的文件在暫存區沒有記錄的,add的時候會把對應的文件拷貝到倉庫中,並在暫存區建立一條索引指向倉庫中對應的文件。

    1.1.3、【改】對工作區的文件內容進行算法得出校驗值與暫存區記錄的校驗值不同,add的時候會把對應的文件拷貝到倉庫中,並更新暫存區該條索引的信息。

  1.2、對比暫存區與當前HEAD所指向的快照,對比結果也是增、刪、改3種情況

2、add

  add會執行2個任務,第一是把【增】【改】的文件拷貝到倉庫,第二個是維護暫存區索引,保證暫存區索引跟操作系統的文件索引內容一致,快照索引指向的是倉庫中的文件,操作系統索引指向的是工作區的文件。

3、commit

  commit做的事情就簡單些了,先對比暫存區與工作區,當暫存區與工作區內容相同的時候,直接保存暫存區為一份新的快照、並給這個快照生成1個編號,並把當前分支HEAD改成這個編號。

4、reset

  reset分2情況:

  4.1、reset文件:reset    b86563   b.txt ,將b86563這份快照中b.txt索引復制到暫存區的b.txt的索引。僅僅是對暫存區的索引進行修改,不影響文件內容,僅僅是修改了文件的關聯。

  4.2、reset HEAD:reset    b86563

    4.2.1、參數--soft:僅僅修改HEAD/版本號。

    4.2.2、參數--mixed:默認參數,修改當前HEAD/版本號,然后用指定的快照覆蓋暫存區,工作區不變。

    4.2.3、參數--hard:修改當前分支HEAD,用參數HEAD關聯的快照覆蓋暫存區,並把工作區恢復到快照創建時的工作區狀態,實際就是對比這份“歷史快照”與工作區,快照中沒有的文件,從工作區刪除,校驗碼不同以及工作區沒有的文件,通過快照找到關聯的文件(倉庫中的),並復制到工作區。

5、checkout

  reset分2情況:

  4.1、checkout HEAD:用HEAD關聯的快照覆蓋暫存區,並把工作區恢復到快照創建時的工作區狀態,checkout 快照與reset --hard的區別就是:checkout是可恢復,reset是不可恢復(后期會刪除倉庫中的文件,checkout不會)

  4.2、checkout分支:checkout   dev ,切換到dev分支,並修改當前版本號為dev上最后一個版本號。如果dev分支不存在,創建一個名為dev的分支,版本號不變。

6、revert

  revert就是創建一個新快照,並把分支HEAD修改為新創建快照的編號,用該快照覆蓋暫存區,並把工作區恢復到快照創建時的工作區狀態。checkout和reset會“丟棄”一些版本日志,cover不會。

總結:

1.暫存區、快照=git的文件系統=索引;倉庫、工作區=我們真正需要的文件內容。

2.安全性:revert>checkout>reset,revert不會影響過去,checkout會丟棄掉一些版本號,reset會丟棄版本號和倉庫中的某些備份文件。

7、遠程倉庫

  工作區的文件是可以編輯的,git倉庫的文件是不能編輯的,git上傳到遠程倉庫或從遠程倉庫下載的時候,並不是下載或上傳全部文件。

  7.1、上傳的時候,遠程倉庫的最新快照編號肯定是包含在本地的快照日志中的,如果不存在,則證明遠程倉庫在上次下載后有改動,這時候要求先pull。反之,git會把本地新增的文件上傳到遠程倉庫,並把新增的快照上傳到遠程快照。通過圖1,我們可以看出git是怎么通過HEAD輕松的找到新增的快照和文件的。

  7.2、下載的時候與上傳同理...

如果還有什么不明白的可以加我QQ:158937496


免責聲明!

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



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