原文來自:https://my.oschina.net/dkvirus/blog/1155172
2.2 版本庫的設(shè)計(jì)原理
> 上一節(jié)介紹了版本庫的概念,這一節(jié)介紹工作空間與版本庫中是如何進(jìn)行交互的。通過揣摩作者是如何設(shè)計(jì) Git 的,來確定我們學(xué)習(xí) Git 究竟要學(xué)習(xí)哪些東東。
1. 將文件添加到版本庫
> 假設(shè)你已經(jīng)按照 2.1 節(jié)創(chuàng)建了版本庫,管理的目錄為 d:\git-demo。
> 接下來先跟著操作一遍,有疑惑先放著,下面會根據(jù)這個例子來介紹具體過程是如何操作的。
在 git-demo 目錄下新建文件 readme.txt
內(nèi)容如下:(d:\git-demo\readme.txt)
create a readme.txtfile.
打開 dos 窗口切換到 git-demo 目錄下
$cdd:\git-demo
輸入 git status 查看狀態(tài)
狀態(tài)值:Untracked files,表示這是一個新增的文件。

將 readme.txt 添加到版本庫
$git add readme.txt
輸入 git status 查看狀態(tài)
狀態(tài)值:Changes to be commited,表示版本庫已經(jīng)知道了工作空間被修改了。

將 readme.txt 提交到版本庫
$git commit -m"add a readme.txt file"
輸入 git status 查看狀態(tài)
狀態(tài)值:nothing to commit,表示工作空間的修改已經(jīng)作為一個版本放到了版本庫。

修改 readme.txt 文件,內(nèi)容如下:(d:\git-demo\readme.txt)
createa readme.txt file.Thisisthesecondrevisionofthe document.
輸入 git status 查看狀態(tài)
狀態(tài)值:Changes not staged for commit,表示版本庫知道文件被修改了,只是還沒有提交。

2. git 設(shè)計(jì)原理
> 通過上面的例子,我們有理由推測 git 在添加/修改文件到版本庫中是這樣操作的:
首先通過 git add 指令將工作區(qū)中的內(nèi)容添加到暫存區(qū);
再通過 git commit 指令將暫存區(qū)中內(nèi)容添加到版本庫中。

相關(guān)概念說明:
工作區(qū):git-demo 目錄(除了 .git 目錄以外)可以認(rèn)為是工作空間
版本庫:.git 目錄可以認(rèn)為是版本庫,其中版本庫中包含兩個東東
stage:叫做暫存區(qū)
master:分支,也就是真正意義上存放版本的倉庫了
> 看到上圖我們不禁會想:為什么 git 的作者在設(shè)計(jì)時不直接將工作區(qū)中修改的文件直接添加到master版本庫中,而要在中間再加一層 stage 暫存區(qū)呢?
dk 想了又想,再次做出推測:
> 抽象成思維導(dǎo)圖就是像下面這樣的:

>這里糾正一個錯誤,將 master 版本庫替換成 master 分支倉庫更合適。

對比上面兩張思維導(dǎo)圖,可得出如下結(jié)論:
如果小明寄快遞到代收點(diǎn),代收點(diǎn)馬上就將快遞送到快遞公司;小紅緊接著又將快遞寄到代收點(diǎn),代收點(diǎn)再次送到快遞工資;與代收點(diǎn)在一天內(nèi)收到小明、小紅、小花的快遞,在晚上的時候一并將快遞送到快遞公司。哪種看起來更好不言而喻。
版本庫,作為一個倉庫保存著不同版本的信息,如果每一次小修改都打一條版本信息放到版本庫,那無疑會大大增加版本庫的容量。最佳實(shí)踐時將一定時間內(nèi)的所有修改作為一條版本放到版本庫中最節(jié)約資源。
如果小明寄快遞到代收點(diǎn),后來發(fā)現(xiàn)東西記錯了,想要取回來,直接去代收點(diǎn)拿回來就可以了。如果沒有代收點(diǎn),小明的快遞直接寄到快遞公司,被快遞公司放到了大貨車上就不是那么容易拿回來了。放到版本庫中的暫存區(qū)也就是方便你撤銷你的修改。
>現(xiàn)在再回過頭來看看 1 中示例代碼,是不是對整個流程知根知底了,對工作區(qū),暫存區(qū)和版本庫的概念也大致熟悉了。如果不熟悉,請將本節(jié)重新閱讀一遍。
3. 暫存區(qū)管理的是修改,不是文件
老的版本控制系統(tǒng)比如 svn,管理的是文件,也就是你每一次將本地代碼提交到倉庫時,實(shí)際上提交的都是文件,而文件如果一多,就會導(dǎo)致同步速度很慢。(使用過 svn 的應(yīng)該有感受)
Git 的作者考慮到這一點(diǎn),舍棄了管理文件的思想,使用管理修改的新新思想,這也就是為什么使用 Git 速度很快的原因。
舉例說明:
在 git-demo 目錄下新建 test.txt 文件
內(nèi)容如下:(d:\git-demo\test.txt)
thisisa test.txt file.
將 test.txt 文件添加到暫存區(qū)
$git add test.txt
修改 test.txt 文件
內(nèi)容如下:
thisisa test.txt file.Thisisthe second revision of the document.
將 test.txt 文件提交到分支倉庫
$git commit -m"add test.txt"
使用 git status 查看狀態(tài)
$git status

我們明明 commit 了 test.txt 文件,為什么還顯示有東西要提交呢?
我們來分析一下這個過程:

在示例代碼中,第一次新增 test.txt 文件后使用 git add 把它放到了暫存區(qū)中;
第二次修改 test.txt 文件后并沒有添加暫存區(qū)而直接使用 git commit 操作將暫存區(qū)中內(nèi)容提交到分支倉庫中。
因此,使用 git status 時可以看到仍然有一個修改,提示值:"Changes not staged for commit"也可以看出有個修改沒有放到暫存區(qū)中,stated 就是暫存區(qū)的意思。
如果管理的是文件,在使用 git commit 時應(yīng)該就將 test.txt 文件直接添加到版本庫中。使用管理修改而不管理文件的目的是讓這個過程變得更快,因?yàn)樾薷目梢允且欢蚊枋鲂缘淖址纯伞?/p>
4. Git 我們主要學(xué)些什么
經(jīng)過上面的學(xué)習(xí),我們知道使用版本控制就是將本地工作區(qū)的代碼在分支倉庫中進(jìn)行備份,而我們關(guān)心的操作就是如何從本地到暫存區(qū)到分支倉庫這一條流水線的正常工作。

本節(jié)我們已經(jīng)學(xué)習(xí)過在這條流水線上新增操作了,在接下來的章節(jié)將學(xué)習(xí)撤銷操作與刪除操作。
當(dāng)然,上述三種操作可以看成是將文件塞到分支倉庫,那么從分支倉庫中將備份取出來也至關(guān)重要,因此,我們還要學(xué)習(xí)如何回滾版本庫中指定備份。
5. 總結(jié)
本節(jié)介紹了 Git 的設(shè)計(jì)原理
主要要掌握工作區(qū)、暫存區(qū)與分支版本庫的概念。
根據(jù)設(shè)計(jì)原理確定接下來的學(xué)習(xí)路線
將本地代碼備份到分支倉庫流水線:工作區(qū) - 暫存區(qū) - 分支倉庫;
已經(jīng)介紹過新增操作,通過 git add 添加到暫存區(qū),通過 git commit 提交到分支倉庫;
接下來學(xué)習(xí)撤銷操作和刪除操作。
介紹了暫存區(qū)時管理修改而不是管理文件
這一點(diǎn)沒看懂的拉上去再看一遍
學(xué)習(xí)到了三個指令
git add
提交工作區(qū)中文件到暫存區(qū)
git commit -m
將暫存區(qū)中所有修改提交到分支倉庫中;
-m 后面緊跟著的是對當(dāng)前版本的一段描述話語,方便以后再分支倉庫中快速找到某個版本;
注意:這里要用雙引號,不能用單引號。
git status
查看文件/目錄在 git-demo 目錄下的狀態(tài),好比收快遞時查的物流信息一樣。
