Git-基礎

最近重新學了一遍Git工具的使用,在此記錄一下。

Git是什么?

Git是屬于分布式版本控制系統,同屬于的還有Mercurial、Bazaar等。
Subversion(svn)屬于集中式的版本控制系統,同屬于的還有CVS、Perforce等。

兩種類型版本控制系統有什么區別?

集中式的版本控制系統,以單臺中央服務器為中心,將所有的版本控制歷史都集中放在這臺服務器上,而各個協同開發者的計算機上只保存著一個快照版本,在這種情況下,開發者每次想要提交或者查看文件的歷史等,都需要請求網絡,向剛剛所說的中央服務器獲取或者提交數據。
分布式版本控制系統與集中式版本控制系統不同,它在本地計算機上建立代碼倉庫,保存著所有的版本控制歷史的數據,在合適的時機與遠程服務器代碼倉庫同步。在這種情況下,開發者每次想要提交或者查看文件的歷史等,無需請求網絡,直接向本地獲取或者提交數據即可,因為本地保存著所有的版本歷史數據。
分布式版本控制系統的優點:
開發者所有的Git操作都在本地代碼倉庫進行,不用依賴于網絡。
不用擔心代碼倉庫服務器宕機或者數據丟失等情況,因為每個開發者計算機上都保存有完整的版本歷史數據,可以隨時將開發者主機上的數據恢復至服務器代碼倉庫。


限于篇幅,本文接下去的內容不討論svn等集中式的版本控制系統與分布式版本系統的用法差異。
為了更加貼近于實際的開發,我們將從Git倉庫的創建到版本的提交為順序講述,最后還簡述一下分支的用法和概念。
注意:本文是在本地代碼倉庫上的操作,還未涉及到遠程倉庫的連接,讀者先不要將遠程倉庫的思想混進來,容易造成混亂。
先介紹幾個Git中的基本概念。

Git中的文件區域

18333fig0106-tn.png

在git中總共有三個區域。分別是工作區、暫存區、git倉庫區。
我們所有的文件修改以及變更都是在工作區進行的,然后保存至暫存區(git add命令),最后保存到git倉庫區(git commit命令)。可能有讀者會問git為什么要設計一個暫存區,為什么不支持從工作區直接將文件保存至git倉庫區。這是因為這個暫存區作為一個中間區域,它的作用就是存放即將要提交到git倉庫的文件。
有這個區域的存在,開發者可以將想要提交到倉庫的文件保存到暫存區,不想提交的文件可以繼續存放在工作區,這樣子下次執行提交操作的時候,Git只會將暫存區所有的文件提交到倉庫中。
開發者提交文件更加靈活。開發者假如后悔不想要提交某個文件(此時這個文件已經在暫存區),那么開發者可以將此文件從暫存區中移出(git reset HEAD <file>命令),下次提交就不會提交這個文件。

Git中的文件狀態

image.png

在git中,文件有四種狀態。未跟蹤、未修改、已修改、已暫存。
已跟蹤的文件是指本來就被納入版本控制管理的文件,在上次快照中有它們的記錄,工作一段時間后,它們的狀態可能是未修改,已修改或者已暫存。
未跟蹤文件既沒有在git倉庫中存有快照,也還未將文件快照保存到當前的暫存區域。初次克隆某個倉庫時,工作目錄中的所有文件都屬于已跟蹤文件,且狀態為未修改。

Git倉庫的創建

Git倉庫的創建非常簡單,在本地設備有安裝Git情況下,直接在項目根目錄下運行shell命令git init即可。

$ git init

git status

git status這個命令是用來檢查當前文件的狀態的。為什么我這么早就介紹這個命令?因為這個命令能給我們提供很多有用的信息,幫助我們了解Git。這個命令應該算是有git最常用的命令了,它能夠顯示當前工作區文件的狀態(已跟蹤或未跟蹤)、暫存區文件狀態、文件沖突狀態、當前所在的分支等。

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   benchmarks.rb

從輸出中可以看到當前處于master分支,新創建的文件README已經被保存至暫存區域,benchmarks.rb在工作區域已被修改,但是還沒被保存至暫存區域,下次提交時候只會提交README文件到代碼倉庫。
括號中的文本是git的輔助提示信息。比如這里git告訴你使用git reset HEAD <file> ...可以將文件從暫存區域移除。git add <file> ...用來添加或者更新文件到暫存區域等到下次提交。用git checkout --<file>命令來還原工作區文件的改變,其實就是將工作區某個或某些文件還原為未修改的狀態。

git add

git add的作用是將工作區的文件保存至暫存區。
重要是事情說三遍!
git 保存的不是文件差異或者變化量,而只是一系列文件快照。
git 保存的不是文件差異或者變化量,而只是一系列文件快照。
git 保存的不是文件差異或者變化量,而只是一系列文件快照。

這個命令的后面可以帶有文件或者文件夾路徑作為參數,當參數為目錄時候,git add的效果會遞歸至目錄下所有的文件。

  • 如果文件在工作區域已被跟蹤,那么直接將文件快照保存至暫存區。
  • 執行git add命令后,git會計算該文件的校驗和,生成該文件快照,將校驗和保存到暫存區,這里是保存文件快照。
    注意:如果執行所要執行git add的目標文件處于未跟蹤狀態,此命令會先將目標文件標識為已跟蹤文件。

在倉庫建立之后,因為此時本地代碼倉庫和暫存區都是空的,并沒有任何文件的快照。所以此時所有的文件狀態都是未跟蹤狀態。
此時執行git status命令:

$ vim README
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        README

nothing added to commit but untracked files present (use "git add" to track)

我們工作目錄下有一個名為README文件,此時顯示它的狀態就是未跟蹤的。同時git也提示我們可以使用git add來跟蹤以及保存到暫存區。

此時我們執行git add *命令(git 命令支持通配符,*表示將當前工作目錄下所有的非忽略文件提交至暫存區,包括所有子文件夾的下的所有文件,當前這里你也可以直接使用git add README命令,指定只作用于README文件)。然后再次執行git status

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   README

從輸出中我們可以看到暫存區已經保存著README文件的快照,并且等待提交。

git commit

git commit這個命令是用來將文件提交到本地代碼倉庫的。
當你用Git commit命令執行一個新的提交時候,Git只保存一個指向這次提交快照的索引。

18333fig0105-tn.png

可以看到這里有三個文件,file A、file B、file C。這里以在提交一個新的版本后,git會遍歷一邊所有的文件的指紋信息,如果發現新版本的文件指紋信息與上一個版本不一致,說明該文件發生了變化,此時git會將新的文件快照索引保存至本地的微型數據庫中,如果文件未發生變化,那么會將上個版本的保存的快照索引直接復用寫入微型數據庫中。

注:git所有的數據都保存在本地項目倉庫的.git文件夾下,這個文件夾默認為隱藏文件夾。

實際上,我們執行一次提交操作就是保存一個提交對象。
當執行git commit命令后,git會先計算每一個子目錄的校驗和(注意,git add是計算文件的校驗和),然后在git倉庫中將這些目錄保存為樹對象,然后git會創建一個提交對象,這個提交對象出了包含相關的提交信息以外,還包含著指向這個樹對象的指針,如此它就可以在將來需要的時候,重現此次快照的內容了。git commit會將暫存區的所有文件提交到本地數據庫中。保存的內容如下。

image

多次提交之后:


image

分支

分支應該算是版本控制系統最強大的功能之一了。
前面我們說了,在執行git提交時,git會創建并且生成一個提交對象,該對象包含一個指向文件樹的指針,包含本次提交的作者等相關附屬信息,包含零個或者多個指向該提交對象的父對象指針:首次提交時沒有直接祖先的,普通提交有一個祖先,由兩個或者多個分支合并產生的提交則有多個祖先。
其實分支的概念很簡單,分支本質上僅僅是個指向某個提交對象的可變指針。
在創建一個新的代碼倉庫時,git會默認創建一個名為master的分支。我們的每次提交操作,都是基于某個分支的基礎上進行的。在若干次提交操作之后,分支會自動向前移動。
分支的創建很簡單。

 git branch testing

這會在當前的提交對象上新建一個新的分支指針。如下:

image

那么,git是如何知道我們當前是在哪個分支上工作的呢?其實git保存著一個名為HEAD的特別指針。每當我們切換執行切換分支操作的時候,git其實只是將HEAD指針移動到目標分支上,這樣子我們接下去的提交等操作都是針對于這個分支進行的。
在上面命令中,我們執行了git branch命令,這個命令僅僅是創建一個分支,而不會切換到新建的這個分支中。要切換分支,可以執行一下命令。

git checkout testing

這樣子,HEAD就指向了testing分支。這樣子就完成了分支的切換。


image

此時我們如果進行修改一個文件,然后提交。結果如下。

vim test.rb
git commit -a -m 'made a change'

注意,git commit 后面-a表示直接跳過保存至暫存區,直接提交到數據庫。


image

好了。我們把分支切回master。然后再次修改一個文件,最后提交。

vim test.rb
git commit -a -m 'made other changes'

結果如下:

image

可以看到,我們的項目提交歷史產生了分叉。這是因為我們的master和testing分支的父提交對象都是f30ab,我們后面可以在合適的時機將兩個分支合并。

關于分支的合并見下章,未完待續。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內容

  • Git 基礎 基本原理 客戶端并不是只提取最新版本的文件快照,而是把代碼倉庫完整的鏡像下來。這樣一來,任何一處協同...
    __silhouette閱讀 15,926評論 5 147
  • Git 命令行學習筆記 Git 基礎 基本原理 客戶端并不是只提取最新版本的文件快照,而是把代碼倉庫完整的鏡像下來...
    sunnyghx閱讀 3,942評論 0 11
  • Git常用語法 [TOC] Git簡介 描述 ? Git(讀音為/g?t/。)是一個開源的分布式版本控制系統,...
    君惜丶閱讀 3,562評論 0 13
  • 仲秋的請柬一簽 白露便馬不停蹄地趕來 邀清風明月為伴 與金黃共同彈奏“豐收”的喜悅 (2020.9.7.) 白云悠...
    一剪紅梅閱讀 617評論 4 23
  • CocoaPods基于Ruby語言開發而成,因此安裝CocoaPods前需要安裝Ruby環境。幸運的是Mac系統默...
    男神已認證閱讀 1,260評論 0 2