1. 程式人生 > >轉——git常見使用命令及git原理

轉——git常見使用命令及git原理

0.常用命令1

1.git中brunch的使用和理解一定理解brunch的指標理解和分叉

分支建立

Git 是怎麼建立新分支的呢? 很簡單,它只是為你建立了一個可以移動的新的指標。 比如,建立一個 testing 分支, 你需要使用 git branch 命令:

$ git branch testing

這會在當前所在的提交物件上建立一個指標。

兩個指向相同提交歷史的分支。 Figure 12. 兩個指向相同提交歷史的分支

那麼,Git 又是怎麼知道當前在哪一個分支上呢? 也很簡單,它有一個名為 HEAD

 的特殊指標。 請注意它和許多其它版本控制系統(如 Subversion 或 CVS)裡的 HEAD 概念完全不同。 在 Git 中,它是一個指標,指向當前所在的本地分支(譯註:將 HEAD 想象為當前分支的別名)。 在本例中,你仍然在 master 分支上。 因為 git branch 命令僅僅 建立 一個新分支,並不會自動切換到新分支中去。

HEAD 指向當前所在的分支。 Figure 13. HEAD 指向當前所在的分支

你可以簡單地使用 git log

 命令檢視各個分支當前所指的物件。 提供這一功能的引數是 --decorate

$ git log --oneline --decorate
f30ab (HEAD, master, testing) add feature #32 - ability to add new
34ac2 fixed bug #1328 - stack overflow under certain conditions
98ca9 initial commit of my project

正如你所見,當前 “master” 和 “testing” 分支均指向校驗和以 f30ab

 開頭的提交物件。

分支切換

要切換到一個已存在的分支,你需要使用 git checkout 命令。 我們現在切換到新建立的 testing 分支去:

$ git checkout testing

這樣 HEAD 就指向 testing 分支了。

HEAD 指向當前所在的分支。 Figure 14. HEAD 指向當前所在的分支

那麼,這樣的實現方式會給我們帶來什麼好處呢? 現在不妨再提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'
HEAD 分支隨著提交操作自動向前移動。 Figure 15. HEAD 分支隨著提交操作自動向前移動

如圖所示,你的 testing 分支向前移動了,但是 master 分支卻沒有,它仍然指向執行 git checkout 時所指的物件。 這就有意思了,現在我們切換回 master 分支看看:

$ git checkout master
檢出時 HEAD 隨之移動。 Figure 16. 檢出時 HEAD 隨之移動

這條命令做了兩件事。 一是使 HEAD 指回 master 分支,二是將工作目錄恢復成 master 分支所指向的快照內容。 也就是說,你現在做修改的話,專案將始於一個較舊的版本。 本質上來講,這就是忽略 testing分支所做的修改,以便於向另一個方向進行開發。

Note 分支切換會改變你工作目錄中的檔案

在切換分支時,一定要注意你工作目錄裡的檔案會被改變。 如果是切換到一個較舊的分支,你的工作目錄會恢復到該分支最後一次提交時的樣子。 如果 Git 不能幹淨利落地完成這個任務,它將禁止切換分支。

我們不妨再稍微做些修改並提交:

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

現在,這個專案的提交歷史已經產生了分叉(參見 專案分叉歷史)。 因為剛才你建立了一個新分支,並切換過去進行了一些工作,隨後又切換回 master 分支進行了另外一些工作。 上述兩次改動針對的是不同分支:你可以在不同分支間不斷地來回切換和工作,並在時機成熟時將它們合併起來。 而所有這些工作,你需要的命令只有 branchcheckout 和 commit

專案分叉歷史。 Figure 17. 專案分叉歷史

你可以簡單地使用 git log 命令檢視分叉歷史。 執行 git log --oneline --decorate --graph --all ,它會輸出你的提交歷史、各個分支的指向以及專案的分支分叉情況。

$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project

由於 Git 的分支實質上僅是包含所指物件校驗和(長度為 40 的 SHA-1 值字串)的檔案,所以它的建立和銷燬都異常高效。 建立一個新分支就相當於往一個檔案中寫入 41 個位元組(40 個字元和 1 個換行符),如此的簡單能不快嗎?

這與過去大多數版本控制系統形成了鮮明的對比,它們在建立分支時,將所有的專案檔案都複製一遍,並儲存到一個特定的目錄。 完成這樣繁瑣的過程通常需要好幾秒鐘,有時甚至需要好幾分鐘。所需時間的長短,完全取決於專案的規模。而在 Git 中,任何規模的專案都能在瞬間建立新分支。 同時,由於每次提交都會記錄父物件,所以尋找恰當的合併基礎(譯註:即共同祖先)也是同樣的簡單和高效。 這些高效的特性使得 Git 鼓勵開發人員頻繁地建立和使用分支。

 

2.使用分支的情況,以及合併分支的兩種不同情況及其操作帶來的問題

2.1實際上當你開發一個新功能時,或者修改一個bug時,為了不影響已經發布的軟體版本,你可以建立一個新分支,以此來保證master分支的完整性。但要注意合併分支時候的兩種情況

master是當前釋出版本的分支,iss53是你正在開發的新功能的分支(未釋出),hotfix是你正在修改釋出版本中bug的分支,第一種合併分支情況,將hotfix分支合併回去,此時不存在衝突,master後退一下就可以了。合併後的情況如下

當你開發好iss53功能後在合併分支就發生了不同的情況,也就是第二種情況,C3跟C4可能發生了衝突,這時候就要解決衝突了

 3.git撤銷本地修改與回退版本

1. 使用 git checkout 撤銷本地修改

即放棄對本地已修改但尚未提交的檔案的修改,還原其到未修改前的狀態。
注意: 已 add/ commit 的檔案不適用個方法,應該用本文提到的第二種方法。

命令如下:

1 git checkout . # 撤銷對所有已修改但未提交的檔案的修改,但不包括新增的檔案
2 git checkout [filename] # 撤銷對指定檔案的修改,[filename]為檔名

2. 使用 git reset 回退專案版本

可以回退到任意已經提交過的版本。已 add / commit 但未 push 的檔案也適用。

命令如下:

1 git reset --hard [commit-hashcode] 
2 # [commit-hashcode]是某個 commit 的雜湊值,可以用 git log 檢視

更復雜的版本回復可以百度,總之總有後悔藥可以吃,

本小節摘自https://blog.csdn.net/dandelion_drq/article/details/51259831