|
git定義:版本管理工具 歷史:沒(méi)有g(shù)it的時(shí)候,我們修改完一個(gè)文件,要先把文件拷貝一個(gè)副本到備份文件夾中,還要建個(gè)文檔來(lái)記錄當(dāng)前文件的信息和操作記錄。當(dāng)文件多的時(shí)候,人工操作起來(lái)將是個(gè)非常辛苦非常龐大的工作量。 如今:有了git幫我們管理這些副本,為我們節(jié)約了非常大的人力成本,讓我們的工作變得更加輕松。我們不要把git看得那么神秘,git的核心就是創(chuàng)建備份和恢復(fù)備份,但是衍生出一堆的新概念,有很多同學(xué)因?yàn)楸焕г谶@些抽象概念上而不能利用好git,本文章是從文件的層面出發(fā)來(lái)理解git原理和git命令是怎么來(lái)創(chuàng)建副本和恢復(fù)副本的。,無(wú)論是分支、HEAD、快照、倉(cāng)庫(kù)、還是工作區(qū)等,都是存在硬盤(pán)上的文件。 基礎(chǔ)理論知識(shí): 1.文件系統(tǒng):我們可以把硬盤(pán)理解成一本漢語(yǔ)詞典,詞典前面的索引部分就是文件系統(tǒng),能幫助我們快速找到文件內(nèi)容的具體位置。我們知道從操作系統(tǒng)刪除文件,其實(shí)只是刪除了索引,具體文件內(nèi)容還是存在硬盤(pán)上的。 2.git快照:快照并不是整個(gè)項(xiàng)目文件夾的副本,快照僅僅是一個(gè)記錄文件結(jié)構(gòu)的文檔。我們知道git是通過(guò)快照來(lái)管理版本的,快照就是git的文件系統(tǒng),每一份快照就是一份文件索引,每次commit就是創(chuàng)建一份快照,并給快照起一個(gè)編號(hào),這個(gè)編號(hào)就是HEAD。在工作中,git通過(guò)head找到快照,通過(guò)快照找到備份到倉(cāng)庫(kù)中的文件。快照記錄了文件的概要信息,包括校驗(yàn)值(通過(guò)對(duì)文件內(nèi)容進(jìn)行一系列算法獲得),通過(guò)對(duì)比兩個(gè)文件的校驗(yàn)值就可以快速判斷兩個(gè)文件內(nèi)容是否一樣。 3.git倉(cāng)庫(kù):倉(cāng)庫(kù)才是真正存放文件內(nèi)容的地方,快照/索引關(guān)聯(lián)的就是倉(cāng)庫(kù)中的文件。沒(méi)有g(shù)it的時(shí)候我們會(huì)把創(chuàng)建的副本拷貝到一個(gè)備份文件夾管理起來(lái),這個(gè)地方現(xiàn)在被git倉(cāng)庫(kù)替代,但是git倉(cāng)庫(kù)不是簡(jiǎn)單的拷貝一份一模一樣的文件,而是經(jīng)過(guò)壓縮的,這些壓縮文件存放在.git/objects目錄中,直接打開(kāi)是亂碼。 4.工作區(qū):工作區(qū)就是除開(kāi).git目錄的其他東西。通過(guò)操作系統(tǒng)的文件索引來(lái)管理的內(nèi)容。就是我們正常使用電腦的時(shí)候所看到,能編輯的內(nèi)容。 5.暫存區(qū)/緩沖區(qū):緩沖區(qū)并不存放文件內(nèi)容,緩沖區(qū)僅僅是一份處于編輯狀態(tài)的快照(索引文件),這份快照沒(méi)有編號(hào)。commit就是把緩沖區(qū)保存一個(gè)副本,并加上一個(gè)編號(hào)(HEAD/版本號(hào))指向這個(gè)快照副本??煺罩斜4娴氖琼?xiàng)目中的所有文件信息,并建立索引跟倉(cāng)庫(kù)中的文件關(guān)聯(lián)起來(lái)。 同學(xué)們可以通過(guò)下面的圖片來(lái)理解以上幾個(gè)概念,下圖中的每個(gè)方塊都是存放在硬盤(pán)上的文件,git就是建立了這樣一個(gè)關(guān)系庫(kù)來(lái)管理版本的。 大家不要被上圖的復(fù)雜線(xiàn)條縮困擾,你只需要弄清HEAD就行了,我們移動(dòng)HEAD指針其實(shí)就是通過(guò)HEAD編號(hào)找到快照,再通過(guò)快照找到這個(gè)HEAD的所有文件。 git命令的理解: 1、status 1.1、對(duì)比緩沖區(qū)跟工作區(qū),對(duì)比結(jié)果主要存在3種情況: 1.1.1、【刪】緩沖區(qū)記錄的文件在工作區(qū)沒(méi)有,add的時(shí)候會(huì)從緩沖區(qū)移除對(duì)應(yīng)的文件索引,但并不影響git倉(cāng)庫(kù)的內(nèi)容。 1.1.2、【增】工作區(qū)已有的文件在緩沖區(qū)沒(méi)有記錄的,add的時(shí)候會(huì)把對(duì)應(yīng)的文件拷貝到倉(cāng)庫(kù)中,并在緩沖區(qū)建立一條索引指向倉(cāng)庫(kù)中對(duì)應(yīng)的文件。 1.1.3、【改】對(duì)工作區(qū)的文件內(nèi)容進(jìn)行算法得出校驗(yàn)值與緩沖區(qū)記錄的校驗(yàn)值不同,add的時(shí)候會(huì)把對(duì)應(yīng)的文件拷貝到倉(cāng)庫(kù)中,并更新緩沖區(qū)該條索引的信息。 1.2、對(duì)比緩沖區(qū)與當(dāng)前HEAD所指向的快照,對(duì)比結(jié)果也是增、刪、改3種情況: 2、add add會(huì)執(zhí)行2個(gè)任務(wù),第一是把【增】【改】的文件拷貝到倉(cāng)庫(kù),第二個(gè)是維護(hù)緩沖區(qū)索引,保證緩沖區(qū)索引跟操作系統(tǒng)的文件索引內(nèi)容一致,快照索引指向的是倉(cāng)庫(kù)中的文件,操作系統(tǒng)索引指向的是工作區(qū)的文件。 3、commit commit做的事情就簡(jiǎn)單些了,先對(duì)比緩沖區(qū)與工作區(qū),當(dāng)緩沖區(qū)與工作區(qū)內(nèi)容相同的時(shí)候,直接保存緩沖區(qū)為一份新的快照、并給這個(gè)快照生成1個(gè)編號(hào),并把當(dāng)前分支HEAD改成這個(gè)編號(hào)。 4、reset reset分2情況: 4.1、reset文件:reset b86563 b.txt ,將b86563這份快照中b.txt索引復(fù)制到緩沖區(qū)的b.txt的索引。僅僅是對(duì)緩沖區(qū)的索引進(jìn)行修改,不影響文件內(nèi)容,僅僅是修改了文件的關(guān)聯(lián)。 4.2、reset HEAD:reset b86563 4.2.1、參數(shù)--soft:僅僅修改HEAD/版本號(hào)。 4.2.2、參數(shù)--mixed:默認(rèn)參數(shù),修改當(dāng)前HEAD/版本號(hào),然后用指定的快照覆蓋緩沖區(qū),工作區(qū)不變。 4.2.3、參數(shù)--hard:修改當(dāng)前HEAD為參數(shù)中的HEAD,用參數(shù)HEAD關(guān)聯(lián)的快照覆蓋緩沖區(qū),并把工作區(qū)恢復(fù)到快照創(chuàng)建時(shí)的工作區(qū)狀態(tài),實(shí)際就是對(duì)比這份“歷史快照”與工作區(qū),快照中沒(méi)有的文件,從工作區(qū)刪除,校驗(yàn)碼不同以及工作區(qū)沒(méi)有的文件,通過(guò)快照找到關(guān)聯(lián)的文件(倉(cāng)庫(kù)中的),并復(fù)制到工作區(qū)。 5、checkout reset分2情況: 4.1、checkout分支:checkout dev ,切換到dev分支,并修改當(dāng)前版本號(hào)為dev上最后一個(gè)版本號(hào)。如果dev分支不存在,創(chuàng)建一個(gè)名為dev的分支,版本號(hào)不變。 4.2、checkout HEAD:用HEAD關(guān)聯(lián)的快照覆蓋緩沖區(qū),并把工作區(qū)恢復(fù)到快照創(chuàng)建時(shí)的工作區(qū)狀態(tài),checkout 快照與reset --hard的卻別就是不修改當(dāng)前HEAD,修改版本號(hào),會(huì)“丟棄”掉該版本號(hào)之后的commit,可以理解成刪除快照,比如我們?cè)诘?個(gè)版本上輸入命令git log,會(huì)看到1、2、3、4、5這些head日志,當(dāng)我們修改當(dāng)前版本號(hào)為3之后再輸入命令git log,就只能看到1、2、3這些head日志了。 6、revert revert就是復(fù)制一個(gè)快照,并把HEAD修改為新創(chuàng)建快照的編號(hào),用該快照覆蓋緩沖區(qū),并把工作區(qū)恢復(fù)到快照創(chuàng)建時(shí)的工作區(qū)狀態(tài)。相當(dāng)于一次checkout +commit 7、遠(yuǎn)程倉(cāng)庫(kù) 工作區(qū)的文件是可以編輯的,git倉(cāng)庫(kù)的文件是不能編輯的,git上傳到遠(yuǎn)程倉(cāng)庫(kù)或從遠(yuǎn)程倉(cāng)庫(kù)下載的時(shí)候,并不是下載或上傳全部文件。 7.1、上傳的時(shí)候,遠(yuǎn)程倉(cāng)庫(kù)的最新快照編號(hào)肯定是包含在本地的快照日志中的,如果不存在,則證明遠(yuǎn)程倉(cāng)庫(kù)在上次下載后有改動(dòng),這時(shí)候要求先pull。反之,git會(huì)把本地新增的文件上傳到遠(yuǎn)程倉(cāng)庫(kù),并把新增的快照上傳到遠(yuǎn)程快照。通過(guò)圖1,我們可以看出git是怎么通過(guò)HEAD輕松的找到新增的快照和文件的。 7.2、下載的時(shí)候與上傳同理... 如果還有什么不明白的可以加我QQ:158937496 |
|
|
來(lái)自: youxd > 《待分類(lèi)》