7.7 重置揭密

2018-02-24 15:22 更新

重置揭密

在繼續(xù)了解更專業(yè)的工具前,我們先討論一下?reset?與?checkout。 在你初次遇到的 Git 命令中,這兩個是最讓人困惑的。 它們能做很多事情,所以看起來我們很難真正地理解并恰當?shù)剡\用它們。 針對這一點,我們先來做一個簡單的比喻。

三棵樹

理解?reset?和?checkout?的最簡方法,就是以 Git 的思維框架(將其作為內(nèi)容管理器)來管理三棵不同的樹。 “樹” 在我們這里的實際意思是 “文件的集合”,而不是指特定的數(shù)據(jù)結(jié)構(gòu)。 (在某些情況下索引看起來并不像一棵樹,不過我們現(xiàn)在的目的是用簡單的方式思考它。)

Git 作為一個系統(tǒng),是以它的一般操作來管理并操縱這三棵樹的:

HEAD 上一次提交的快照,下一次提交的父結(jié)點

Index

|

預期的下一次提交的快照

Working Directory

|

沙盒

|

HEAD

HEAD 是當前分支引用的指針,它總是指向該分支上的最后一次提交。 這表示 HEAD 將是下一次提交的父結(jié)點。 通常,理解 HEAD 的最簡方式,就是將它看做?你的上一次提交?的快照。

其實,查看快照的樣子很容易。 下例就顯示了 HEAD 快照實際的目錄列表,以及其中每個文件的 SHA-1 校驗和:

$ git cat-file -p HEAD
tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
author Scott Chacon  1301511835 -0700
committer Scott Chacon  1301511835 -0700

initial commit

$ git ls-tree -r HEAD
100644 blob a906cb2a4a904a152...   README
100644 blob 8f94139338f9404f2...   Rakefile
040000 tree 99f1a6d12cb4b6f19...   lib

cat-file?與?ls-tree?是底層命令,它們一般用于底層工作,在日常工作中并不使用。不過它們能幫助我們了解到底發(fā)生了什么。

索引

索引是你的?預期的下一次提交。 我們也會將這個概念引用為 Git 的 “暫存區(qū)域”,這就是當你運行?git commit?時 Git 看起來的樣子。

Git 將上一次檢出到工作目錄中的所有文件填充到索引區(qū),它們看起來就像最初被檢出時的樣子。 之后你會將其中一些文件替換為新版本,接著通過?git commit?將它們轉(zhuǎn)換為樹來用作新的提交。

$ git ls-files -s
100644 a906cb2a4a904a152e80877d4088654daad0c859 0   README
100644 8f94139338f9404f26296befa88755fc2598c289 0   Rakefile
100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0   lib/simplegit.rb

再說一次,我們在這里又用到了?ls-files?這個幕后的命令,它會顯示出索引當前的樣子。

確切來說,索引并非技術(shù)上的樹結(jié)構(gòu),它其實是以扁平的清單實現(xiàn)的。不過對我們而言,把它當做樹就夠了。

工作目錄

最后,你就有了自己的工作目錄。 另外兩棵樹以一種高效但并不直觀的方式,將它們的內(nèi)容存儲在.git?文件夾中。 工作目錄會將它們解包為實際的文件以便編輯。 你可以把工作目錄當做?沙盒。在你將修改提交到暫存區(qū)并記錄到歷史之前,可以隨意更改。

$ tree
.
├── README
├── Rakefile
└── lib
    └── simplegit.rb

1 directory, 3 files

工作流程

Git 主要的目的是通過操縱這三棵樹來以更加連續(xù)的狀態(tài)記錄項目的快照。

Figure 7-3.

此時,只有工作目錄有內(nèi)容。

現(xiàn)在我們想要提交這個文件,所以用?git add?來獲取工作目錄中的內(nèi)容,并將其復制到索引中。

Figure 7-5.

此時如果我們運行?git status,會發(fā)現(xiàn)沒有任何改動,因為現(xiàn)在三棵樹完全相同。

現(xiàn)在我們想要對文件進行修改然后提交它。 我們將會經(jīng)歷同樣的過程;首先在工作目錄中修改文件。 我們稱其為該文件的?v2?版本,并將它標記為紅色。

Figure 7-7.

此時,由于索引和 HEAD 不同,若運行?git status?的話就會看到 “Changes to be committed” 下的該文件變?yōu)榫G色 ——也就是說,現(xiàn)在預期的下一次提交與上一次提交不同。 最后,我們運行?git commit?來完成提交。

壓縮

我們來看看如何利用這種新的功能來做一些有趣的事情 - 壓縮提交。

假設(shè)你的一系列提交信息中有 “oops.”、“WIP” 和 “forgot this file”, 聰明的你就能使用reset?來輕松快速地將它們壓縮成單個提交,也顯出你的聰明。 (壓縮提交?展示了另一種方式,不過在本例中用?reset?更簡單。)

假設(shè)你有一個項目,第一次提交中有一個文件,第二次提交增加了一個新的文件并修改了第一個文件,第三次提交再次修改了第一個文件。 由于第二次提交是一個未完成的工作,因此你想要壓縮它。

Figure 7-17.

然后只需再次運行?git commit

總結(jié)

希望你現(xiàn)在熟悉并理解了?reset?命令,不過關(guān)于它和?checkout?之間的區(qū)別,你可能還是會有點困惑,畢竟不太可能記住不同調(diào)用的所有規(guī)則。

下面的速查表列出了命令對樹的影響。 “HEAD” 一列中的 “REF” 表示該命令移動了 HEAD 指向的分支引用,而“HEAD” 則表示只移動了 HEAD 自身。 特別注意?WD Safe??一列 - 如果它標記為NO,那么運行該命令之前請考慮一下。

Commit Level

reset --soft [commit]

|

REF

|

NO

|

NO

|

YES

reset [commit]

|

REF

|

YES

|

NO

|

YES

reset --hard [commit]

|

REF

|

YES

|

YES

|

NO

checkout [commit]

|

HEAD

|

YES

|

YES

|

YES

File Level

reset (commit) [file]

|

NO

|

YES

|

NO

|

YES

checkout (commit) [file]

|

NO

|

YES

|

YES

|

NO

|

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號