GIT - 一些基本概念

這篇博客將會介紹一點GIT的基本概念,重點是文件狀態以及對應的GIT工程的三種目錄,尤其是暫存區(stage area)。有點枯燥,但應該對大家瞭解GIT有一定的幫助

一點GIT的概念

幾乎所有的操作都在本地

  用過集中式版本控制系統(CVCS)的同學都知道,斷網意味着你基本沒法正常工作。記得07-08年那會還在用IBM的Clearcase,如果你發現開發部門突然一陣騷動,並有人開始在走廊聊天的時候,那就是斷網的時候!我覺得這是CVCS帶給我們最大的好處:中場休息! 因爲在CVCS中,每一個對文件的操作都必須跟服務器溝通,如果斷網基本就沒法幹活。當然,你說我直接在Windows的文件系統修改文件行不行?應該是行的,但要是你rename了這個文件的話,一會未必能checkin成功。 但如果在斷網的時候,你是沒有辦法看到一個文件的歷史記錄的,因爲每個文件的歷史記錄都保存在服務器的。
  而上的各種不爽在GIT這種分佈式版本控制系統裏面就不會存在的!在GIT裏面,除了你要拿到別人的代碼改動,或者你想把代碼改動提交到服務器上 這兩個動作之外,其它的動作基本都可以在斷網的情況下 通行無阻!因爲在本地已經有了一份完整的歷史版本庫 能滿足你99%的工作需要!

三個狀態三座屋

  在GIT的世界裏,每個文件的狀態不是tracked就是untracked。 track指的是該文件已經在GIT的監控範圍之內了,該文件的每一點改動GIT都能跟蹤到;untrack指的是該文件不在GIT的監控範圍之內,它的改動GIT是不會去跟蹤的。
  而每個tracked的文件將會處於如下四種狀態的其中一種:unmodified,modified,staged, committed。

  • unmodified說的就是這個文件木有動過

  • modified是指你的文件已經改動了,但是還沒有保存到你的本地數據庫裏面;

  • staged是指你的文件改動了,並且添加到暫存區裏面,下次提交就會把這些改動保存到本地數據庫;
  • committed是指你的文件改動了,並且已經保存到本地數據庫

    每個真正進入版本庫的文件都需要按照這種順序執行:modified -> staged -> committed。同時這三種狀態是互斥的,也就是說一個文件只能同時處於其中的一種狀態而已!

      上面的這三種狀態也就引出了每個GIT工程的三個組成部分: git目錄(Git Directory),工作目錄(Working Directory),以及暫存區(stage area).

    • Git目錄(Git Directory)
      Git目錄是GIT裏面最重要的一部分,文件夾名字爲”.git”。你從服務器clone一個項目的時候,其實就是clone一個”.git”的文件夾! Git目錄裏面包括了所有的元數據:當前分支,所有本地分支,remote信息,配置文件等等,另外最重要也是最大的就是 所有的GIT對象,這些GIT對象記錄了所有的歷史記錄以及文件改動!

    • Working Directory
      從GIT角度看,一個工作目錄就是GIT的一個版本,裏面的文件是從壓縮的GIT數據庫裏面解壓出來,然後放在你的文件系統裏。
      從使用的角度看,我們開發時用到的所有文件都是 工作目錄 裏面的文件。
      這些文件都放在 項目的根目錄下,跟”.git”在同一文件層次目錄

    • 暫存區(Stage Area)
      暫存區保存着下一個commit將會包含的所有改動。但實際上,暫存區只是一個文件,而不是一個文件夾。暫存區的這個文件一般叫”index”,保存在”.git”目錄下。
      暫存區確實是GIT裏面比較難懂的概念,可能也因爲難懂,所以經常被遺忘!這裏嘗試着多說一點,但願沒有誤導到大家。
      首先我們看看如何將一個文件加到暫存區。當然我們要先對文件做修改
      $ echo haha >>README.md
      這時我們查看當前項目的狀態:

$ git status
    On branch D1.2
    Your branch is up-to-date with 'origin/D1.2'.

    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:   README.md

    no changes added to commit (use "git add" and/or "git commit -a")

從上面GIT詳盡的說明中,我們已經看到了GIT跟蹤到文件README.md已經處於modified的狀態了。而且GIT也已經告訴我們該如何將文件加到暫存區了,我們接着來:

$ git add README.md

這時我們再看看當前項目的狀態:

 $ git status
    On branch D1.2
    Your branch is up-to-date with 'origin/D1.2'.

    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)

            modified:   README.md

GIT的信息裏面說明了README.md的改動已經在暫存區裏面了,下一個commit將會包含這個文件的改動。

其實當我們執行 git add 命令的時候,GIT做了兩件事情:
1. 將本地文件的內容做個快照,並保存到GIT的對象庫裏面(.git/objects)
2. 將本地文件的時間戳,長度以及 第一步保存的對象ID保存到 暫存區(.git/index)裏面去

我們可以來做一個比較大膽的比喻,能從某種程度上解釋暫存區的作用。文件修改就好比是 商品,暫存區就好比是購物車。當我們修改好文件(選好商品)之後,通過 git add命令(拿起商品放到)放到暫存區 (購物車),然後通過commit(買單)將改動加到代碼庫(將商品拿回家裏去)。當然,在這個過程當中,暫存區的文件是可以再回到工作區的(把商品放回貨架上)

commit文件 購買商品
修改文件README.md 挑選商品
git add README.md 把商品放到購物車
git reset HEAD README.md 沒想好,把一些商品放回去
git commit 買單

  
下面這張《ProGit》書中的插圖能很好地說明這三個目錄之間的關係:

Working Directory, Staging Area, Git Directory

以上就是今天想跟大家分享的GIT基本概念,但願沒有誤導大家,要是能有那麼一點點幫助,那碼幾個鐘頭也就值得了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章