添加微信公眾號《Linux就該這么學》,掌握最新IT資訊動態,免費領取Linux課程以及專業的RHCE考前答疑服務。
《Linux就該這么學》在線免費閱讀地址:http://www.linuxprobe.com/
純手工打造每一篇開源資訊與技術干貨,數十萬程序員和Linuxer已經關注
導讀 |
幾乎所有的版本控制系統都以某種形式支持分支。 使用分支意味著你可以把你的工作從開發主線上分離開來,以免影響開發主線。 在很多版本控制系統中,這是一個略微低效的過程——常常需要完全創建一個源代碼目錄的副本。對于大項目來說,這樣的過程會耗費很多時間。 |
1
?Git 分支 - 分支簡介
有人把 Git 的分支模型稱為它的“必殺技特性”,也正因為這一特性,使得 Git 從眾多版本控制系統中脫穎而出。 為何 Git 的分支模型如此出眾呢? Git 處理分支的方式可謂是難以置信的輕量,創建新分支這一操作幾乎能在瞬間完成,并且在不同分支之間的切換操作也是一樣便捷。 與許多其它版本控制系統不同,Git 鼓勵在工作流程中頻繁地使用分支與合并,哪怕一天之內進行許多次。 理解和精通這一特性,你便會意識到 Git 是如此的強大而又獨特,并且從此真正改變你的開發方式。
分支簡介
為了真正理解 Git 處理分支的方式,我們需要回顧一下 Git 是如何保存數據的。
或許你還記得?起步?的內容,Git 保存的不是文件的變化或者差異,而是一系列不同時刻的文件快照。
在進行提交操作時,Git 會保存一個提交對象(commit object)。知道了 Git 保存數據的方式,我們可以很自然的想到——該提交對象會包含一個指向暫存內容快照的指針。 但不僅僅是這樣,該提交對象還包含了作者的姓名和郵箱、提交時輸入的信息以及指向它的父對象的指針。首次提交產生的提交對象沒有父對象,普通提交操作產生的提交對象有一個父對象,而由多個分支合并產生的提交對象有多個父對象,
為了說得更加形象,我們假設現在有一個工作目錄,里面包含了三個將要被暫存和提交的文件。 暫存操作會為每一個文件計算校驗和(使用我們在?起步?中提到的 SHA-1 哈希算法),然后會把當前版本的文件快照保存到 Git 倉庫中(Git 使用 blob 對象來保存它們),最終將校驗和加入到暫存區域等待提交:
$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'
當使用?git commit?進行提交操作時,Git 會先計算每一個子目錄(本例中只有項目根目錄)的校驗和,然后在 Git 倉庫中這些校驗和保存為樹對象。 隨后,Git 便會創建一個提交對象,它除了包含上面提到的那些信息外,還包含指向這個樹對象(項目根目錄)的指針。如此一來,Git 就可以在需要的時候重現此次保存的快照。
現在,Git 倉庫中有五個對象:三個 blob 對象(保存著文件快照)、一個樹對象(記錄著目錄結構和 blob 對象索引)以及一個提交對象(包含著指向前述樹對象的指針和所有提交信息)。
Figure 3-1.?首次提交對象及其樹結構做些修改后再次提交,那么這次產生的提交對象會包含一個指向上次提交對象(父對象)的指針。
Figure 3-2.?提交對象及其父對象Git 的分支,其實本質上僅僅是指向提交對象的可變指針。 Git 的默認分支名字是?master。 在多次提交操作之后,你其實已經有一個指向最后那個提交對象的?master?分支。 它會在每次的提交操作中自動向前移動。
NOTE
Git 的 “master” 分支并不是一個特殊分支。?它就跟其它分支完全沒有區別。 之所以幾乎每一個倉庫都有 master 分支,是因為?git init?命令默認創建它,并且大多數人都懶得去改動它。
Figure 3-3.?分支及其提交歷史
分支創建
Git 是怎么創建新分支的呢? 很簡單,它只是為你創建了一個可以移動的新的指針。 比如,創建一個 testing 分支, 你需要使用?git branch?命令:
git branch testing
這會在當前所在的提交對象上創建一個指針。
Figure 3-4.?兩個指向相同提交歷史的分支那么,Git 又是怎么知道當前在哪一個分支上呢? 也很簡單,它有一個名為?HEAD?的特殊指針。 請注意它和許多其它版本控制系統(如 Subversion 或 CVS)里的HEAD概念完全不同。 在 Git 中,它是一個指針,指向當前所在的本地分支(譯注:將?HEAD?想象為當前分支的別名)。 在本例中,你仍然在master?分支上。 因為?git branch?命令僅僅?創建?一個新分支,并不會自動切換到新分支中去。
Figure 3-5.?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?分支了。
Figure 3-6.?HEAD 指向當前所在的分支那么,這樣的實現方式會給我們帶來什么好處呢? 現在不妨再提交一次:
vim test.rb
git commit -a -m 'made a change'
Figure 3-7.?HEAD 分支隨著提交操作自動向前移動如圖所示,你的testing分支向前移動了,但是?master?分支卻沒有,它仍然指向運行?git checkout?時所指的對象。 這就有意思了,現在我們切換回?master?分支看看:
git checkout master
Figure 3-8.?檢出時 HEAD 隨之移動這條命令做了兩件事。 一是使 HEAD 指回?master?分支,二是將工作目錄恢復成?master?分支所指向的快照內容。 也就是說,你現在做修改的話,項目將始于一個較舊的版本。 本質上來講,這就是忽略testing?分支所做的修改,以便于向另一個方向進行開發。
2
分支切換會改變你工作目錄中的文件
在切換分支時,一定要注意你工作目錄里的文件會被改變。 如果是切換到一個較舊的分支,你的工作目錄會恢復到該分支最后一次提交時的樣子。 如果 Git 不能干凈利落地完成這個任務,它將禁止切換分支。
我們不妨再稍微做些修改并提交:
$ vim test.rb
$ git commit -a -m 'made other changes'
現在,這個項目的提交歷史已經產生了分叉(參見?Figure?3-9)。 因為剛才你創建了一個新分支,并切換過去進行了一些工作,隨后又切換回 master 分支進行了另外一些工作。 上述兩次改動針對的是不同分支:你可以在不同分支間不斷地來回切換和工作,并在時機成熟時將它們合并起來。 而所有這些工作,你需要的命令只有?branch、checkout?和?commit。
Figure 3-9.?項目分叉歷史你可以簡單地使用?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 鼓勵開發人員頻繁地創建和使用分支。
接下來,讓我們看看為什么你應該這么做?
3
Git 分支 - 分支的新建與合并
分支的新建與合并
讓我們來看一個簡單的分支新建與分支合并的例子,實際工作中你可能會用到類似的工作流。 你將經歷如下步驟:
開發某個網站。
為實現某個新的需求,創建一個分支。
在這個分支上開展工作。
正在此時,你突然接到一個電話說有個很嚴重的問題需要緊急修補。 你將按照如下方式來處理:
切換到你的線上分支(production branch)。
為這個緊急任務新建一個分支,并在其中修復它。
在測試通過之后,切換回線上分支,然后合并這個修補分支,最后將改動推送到線上分支。
切換回你最初工作的分支上,繼續工作。
新建分支
首先,我們假設你正在你的項目上工作,并且已經有一些提交。
Figure 3-10.?一個簡單提交歷史現在,你已經決定要解決你的公司使用的問題追蹤系統中的 #53 問題。 想要新建一個分支并同時切換到那個分支上,你可以運行一個帶有?-b?參數的?git checkout?命令:
$ git checkout -b iss53
Switched to a new branch "iss53"
它是下面兩條命令的簡寫:
$ git branch iss53
$ git checkout iss53
Figure 3-11.?創建一個新分支指針你繼續在 #53 問題上工作,并且做了一些提交。 在此過程中,iss53?分支在不斷的向前推進,因為你已經檢出到該分支(也就是說,你的?HEAD?指針指向了?iss53?分支)
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
Figure 3-12.?iss53 分支隨著工作的進展向前推進現在你接到那個電話,有個緊急問題等待你來解決。 有了 Git 的幫助,你不必把這個緊急問題和?iss53的修改混在一起,你也不需要花大力氣來還原關于 53# 問題的修改,然后再添加關于這個緊急問題的修改,最后將這個修改提交到線上分支。 你所要做的僅僅是切換回?master?分支。
但是,在你這么做之前,要留意你的工作目錄和暫存區里那些還沒有被提交的修改,它可能會和你即將檢出的分支產生沖突從而阻止 Git 切換到該分支。 最好的方法是,在你切換分支之前,保持好一個干凈的狀態。 有一些方法可以繞過這個問題(即,保存進度(stashing) 和 修補提交(commit amending)),我們會在?儲藏與清理?中看到關于這兩個命令的介紹。 現在,我們假設你已經把你的修改全部提交了,這時你可以切換回?master?分支了:
$ git checkout master
Switched to branch 'master'
這個時候,你的工作目錄和你在開始 #53 問題之前一模一樣,現在你可以專心修復緊急問題了。 請牢記:當你切換分支的時候,Git 會重置你的工作目錄,使其看起來像回到了你在那個分支上最后一次提交的樣子。 Git 會自動添加、刪除、修改文件以確保此時你的工作目錄和這個分支最后一次提交時的樣子一模一樣。
接下來,你要修復這個緊急問題。 讓我們建立一個針對該緊急問題的分支(hotfix branch),在該分支上工作直到問題解決:
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)
Figure 3-13.?基于?master?分支的緊急問題分支?hotfix branch你可以運行你的測試,確保你的修改是正確的,然后將其合并回你的?master?分支來部署到線上。 你可以使用?git merge?命令來達到上述目的:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
在合并的時候,你應該注意到了"快進(fast-forward)"這個詞。 由于當前?master?分支所指向的提交是你當前提交(有關 hotfix 的提交)的直接上游,所以 Git 只是簡單的將指針向前移動。 換句話說,當你試圖合并兩個分支時,如果順著一個分支走下去能夠到達另一個分支,那么 Git 在合并兩者的時候,只會簡單的將指針向前推進(指針右移),因為這種情況下的合并操作沒有需要解決的分歧——這就叫做 “快進(fast-forward)”。
現在,最新的修改已經在?master?分支所指向的提交快照中,你可以著手發布該修復了。
Figure 3-14.?master?被快進到?hotfix關于這個緊急問題的解決方案發布之后,你準備回到被打斷之前時的工作中。 然而,你應該先刪除hotfix?分支,因為你已經不再需要它了 ——?master?分支已經指向了同一個位置。 你可以使用帶?-d選項的?git branch?命令來刪除分支:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
現在你可以切換回你正在工作的分支繼續你的工作,也就是針對 #53 問題的那個分支(iss53 分支)。
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
Figure 3-15.?繼續在?iss53?分支上的工作你在?hotfix?分支上所做的工作并沒有包含到?iss53?分支中。 如果你需要拉取?hotfix?所做的修改,你可以使用?git merge master?命令將?master?分支合并入?iss53?分支,或者你也可以等到?iss53分支完成其使命,再將其合并回?master?分支。
分支的合并
假設你已經修正了 #53 問題,并且打算將你的工作合并入?master?分支。 為此,你需要合并?iss53?分支到?master?分支,這和之前你合并?hotfix?分支所做的工作差不多。 你只需要檢出到你想合并入的分支,然后運行?git merge?命令:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | ? ?1 +
1 file changed, 1 insertion(+)
這和你之前合并?hotfix?分支的時候看起來有一點不一樣。 在這種情況下,你的開發歷史從一個更早的地方開始分叉開來(diverged)。 因為,master?分支所在提交并不是?iss53?分支所在提交的直接祖先,Git 不得不做一些額外的工作。 出現這種情況的時候,Git 會使用兩個分支的末端所指的快照(C4和?C5)以及這兩個分支的工作祖先(C2),做一個簡單的三方合并。
Figure 3-16.?一次典型合并中所用到的三個快照和之間將分支指針向前推進所不同的是,Git 將此次三方合并的結果做了一個新的快照并且自動創建一個新的提交指向它。 這個被稱作一次合并提交,它的特別之處在于他有不止一個父提交。
Figure 3-17.?一個合并提交需要指出的是,Git 會自行決定選取哪一個提交作為最優的共同祖先,并以此作為合并的基礎;這和更加古老的 CVS 系統或者 Subversion (1.5 版本之前)不同,在這些古老的版本管理系統中,用戶需要自己選擇最佳的合并基礎。 Git 的這個優勢使其在合并操作上比其他系統要簡單很多。
既然你的修改已經合并進來了,你已經不再需要?iss53?分支了。 現在你可以在任務追蹤系統中關閉此項任務,并刪除這個分支。
$ git branch -d iss53
遇到沖突時的分支合并
有時候合并操作不會如此順利。 如果你在兩個不同的分支中,對同一個文件的同一個部分進行了不同的修改,Git 就沒法干凈的合并它們。 如果你對 #53 問題的修改和有關?hotfix?的修改都涉及到同一個文件的同一處,在合并它們的時候就會產生合并沖突:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
此時 Git 做了合并,但是沒有自動地創建一個新的合并提交。 Git 會暫停下來,等待你去解決合并產生的沖突。 你可以在合并沖突后的任意時刻使用?git status?命令來查看那些因包含合并沖突而處于未合并(unmerged)狀態的文件:
$ git status
On branch master
You have unmerged paths.
?(fix conflicts and run "git commit")
Unmerged paths:
?(use "git add <file>..." to mark resolution)
? ?both modified: ? ? ?index.html
no changes added to commit (use "git add" and/or "git commit -a")
任何因包含合并沖突而有待解決的文件,都會以未合并狀態標識出來。 Git 會在有沖突的文件中加入標準的沖突解決標記,這樣你可以打開這些包含沖突的文件然后手動解決沖突。 出現沖突的文件會包含一些特殊區段,看起來像下面這個樣子:
<<<<<<< HEAD:index.html
<div >contact : email.support@github.com</div>
=======
<div >
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
這表示?HEAD?所指示的版本(也就是你的?master?分支所在的位置,因為你在運行 merge 命令的時候已經檢出到了這個分支)在這個區段的上半部分(=======?的上半部分),而?iss53?分支所指示的版本在=======?的下半部分。 為了解決沖突,你必須選擇使用由?=======?分割的兩部分中的一個,或者你也可以自行合并這些內容。 例如,你可以通過把這段內容換成下面的樣子來解決沖突:
<div >
please contact us at email.support@github.com</div>
上述的沖突解決方案僅保留了其中一個分支的修改,并且?<<<<<<<?,?=======?, 和?>>>>>>>?這些行被完全刪除了。 在你解決了所有文件里的沖突之后,對每個文件使用?git add?命令來將其標記為沖突已解決。 一旦暫存這些原本有沖突的文件,Git 就會將它們標記為沖突已解決。
如果你想使用圖形化工具來解決沖突,你可以運行?git mergetool,該命令會為你啟動一個合適的可視化合并工具,并帶領你一步一步解決這些沖突:
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
?{local}: modified file
?{remote}: modified file
Hit return to start merge resolution tool (opendiff):
如果你想使用除默認工具(在這里 Git 使用?opendiff?做為默認的合并工具,因為作者在 Mac 上運行該程序)外的其他合并工具,你可以在 “下列工具中(one of the following tools)” 這句后面看到所有支持的合并工具。 然后輸入你喜歡的工具名字就可以了。
NOTE
等你退出合并工具之后,Git 會詢問剛才的合并是否成功。 如果你回答是,Git 會暫存那些文件以表明沖突已解決: 你可以再次運行?git status?來確認所有的合并沖突都已被解決:
$ git status
On branch master
All conflicts fixed but you are still merging.
?(use "git commit" to conclude merge)
Changes to be committed:
? ?modified: ? index.html
如果你對結果感到滿意,并且確定之前有沖突的的文件都已經暫存了,這時你可以輸入?git commit?來完成合并提交。 默認情況下提交信息看起來像下面這個樣子:
Merge branch 'iss53'
Conflicts:
? ?index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: ? index.html
#
如果你覺得上述的信息不夠充分,不能完全體現分支合并的過程,你可以修改上述信息,添加一些細節給未來檢視這個合并的讀者一些幫助,告訴他們你是如何解決合并沖突的,以及理由是什么。
4
Git 分支 - 分支管理
分支管理
現在已經創建、合并、刪除了一些分支,讓我們看看一些常用的分支管理工具。
git branch?命令不只是可以創建與刪除分支。?如果不加任何參數運行它,會得到當前所有分支的一個列表:
$ git branch
?iss53
* master
?testing
注意?master?分支前的?*?字符:它代表現在檢出的那一個分支(也就是說,當前?HEAD?指針所指向的分支)。 這意味著如果在這時候提交,master?分支將會隨著新的工作向前移動。 如果需要查看每一個分支的最后一次提交,可以運行?git branch -v?命令:
$ git branch -v
?iss53 ? 93b412c fix javascript issue
* master ?7a98805 Merge branch 'iss53'
?testing 782fd34 add scott to the author list in the readmes
--merged?與?--no-merged?這兩個有用的選項可以過濾這個列表中已經合并或尚未合并到當前分支的分支。 如果要查看哪些分支已經合并到當前分支,可以運行?git branch --merged:
$ git branch --merged
?iss53
* master
因為之前已經合并了?iss53?分支,所以現在看到它在列表中。 在這個列表中分支名字前沒有?*?號的分支通常可以使用?git branch -d?刪除掉;你已經將它們的工作整合到了另一個分支,所以并不會失去任何東西。
查看所有包含未合并工作的分支,可以運行?git branch --no-merged:
$ git branch --no-merged
?testing
這里顯示了其他分支。 因為它包含了還未合并的工作,嘗試使用?git branch -d?命令刪除它時會失敗:
$ git branch -d testing
error: The branch 'testing' is not fully merged.
If you are sure you want to delete it, run 'git branch -D testing'.
如果真的想要刪除分支并丟掉那些工作,如同幫助信息里所指出的,可以使用?-D?選項強制刪除它。
5
Git 分支 - 分支開發工作流
分支開發工作流
現在你已經學會新建和合并分支,那么你可以或者應該用它來做些什么呢? 在本節,我們會介紹一些常見的利用分支進行開發的工作流程。而正是由于分支管理的便捷,才衍生出這些典型的工作模式,你可以根據項目實際情況選擇一種用用看。
長期分支
因為 Git 使用簡單的三方合并,所以就算在一段較長的時間內,反復把一個分支合并入另一個分支,也不是什么難事。 也就是說,在整個項目開發周期的不同階段,你可以同時擁有多個開放的分支;你可以定期地把某些特性分支合并入其他分支中。
許多使用 Git 的開發者都喜歡使用這種方式來工作,比如只在?master?分支上保留完全穩定的代碼——有可能僅僅是已經發布或即將發布的代碼。 他們還有一些名為?develop?或者?next?的平行分支,被用來做后續開發或者測試穩定性——這些分支不必保持絕對穩定,但是一旦達到穩定狀態,它們就可以被合并入?master?分支了。 這樣,在確保這些已完成的特性分支(短期分支,比如之前的?iss53?分支)能夠通過所有測試,并且不會引入更多 bug 之后,就可以合并入主干分支中,等待下一次的發布。
事實上我們剛才討論的,是隨著你的提交而不斷右移的指針。 穩定分支的指針總是在提交歷史中落后一大截,而前沿分支的指針往往比較靠前。
Figure 3-18.?漸進穩定分支的線性圖通常把他們想象成流水線(work silos)可能更好理解一點,那些經過測試考驗的提交會被遴選到更加穩定的流水線上去。
Figure 3-19.?漸進穩定分支的流水線(“silo”)視圖你可以用這種方法維護不同層次的穩定性。 一些大型項目還有一個?proposed(建議) 或?pu: proposed updates(建議更新)分支,它可能因包含一些不成熟的內容而不能進入?next?或者?master分支。 這么做的目的是使你的分支具有不同級別的穩定性;當它們具有一定程度的穩定性后,再把它們合并入具有更高級別穩定性的分支中。 再次強調一下,使用多個長期分支的方法并非必要,但是這么做通常很有幫助,尤其是當你在一個非常龐大或者復雜的項目中工作時。
特性分支
特性分支對任何規模的項目都適用。 特性分支是一種短期分支,它被用來實現單一特性或其相關工作。 也許你從來沒有在其他的版本控制系統(VCS)上這么做過,因為在那些版本控制系統中創建和合并分支通常很費勁。 然而,在 Git 中一天之內多次創建、使用、合并、刪除分支都很常見。
你已經在上一節中你創建的?iss53?和?hotfix?特性分支中看到過這種用法。 你在上一節用到的特性分支(iss53?和?hotfix?分支)中提交了一些更新,并且在它們合并入主干分支之后,你又刪除了它們。 這項技術能使你快速并且完整地進行上下文切換(context-switch)——因為你的工作被分散到不同的流水線中,在不同的流水線中每個分支都僅與其目標特性相關,因此,在做代碼審查之類的工作的時候就能更加容易地看出你做了哪些改動。 你可以把做出的改動在特性分支中保留幾分鐘、幾天甚至幾個月,等它們成熟之后再合并,而不用在乎它們建立的順序或工作進度。
考慮這樣一個例子,你在?master?分支上工作到?C1,這時為了解決一個問題而新建?iss91?分支,在iss91?分支上工作到?C4,然而對于那個問題你又有了新的想法,于是你再新建一個?iss91v2?分支試圖用另一種方法解決那個問題,接著你回到?master?分支工作了一會兒,你又冒出了一個不太確定的想法,你便在?C10?的時候新建一個?dumbidea?分支,并在上面做些實驗。 你的提交歷史看起來像下面這個樣子:
Figure 3-20.?擁有多個特性分支的提交歷史現在,我們假設兩件事情:你決定使用第二個方案來解決那個問題,即使用在?iss91v2?分支中方案;另外,你將?dumbidea?分支拿給你的同事看過之后,結果發現這是個驚人之舉。 這時你可以拋棄?iss91分支(即丟棄?C5?和?C6?提交),然后把另外兩個分支合并入主干分支。 最終你的提交歷史看起來像下面這個樣子:
Figure 3-21.?合并了?dumbidea?和?iss91v2?分支之后的提交歷史我們將會在?分布式 Git?中向你揭示更多有關分支工作流的細節,因此,請確保你閱讀完那個章節之后,再來決定你的下個項目要使用什么樣的分支策略(branching scheme)。
請牢記,當你做這么多操作的時候,這些分支全部都存于本地。 當你新建和合并分支的時候,所有這一切都只發生在你本地的 Git 版本庫中 —— 沒有與服務器發生交互。
原文來自:http://blog.csdn.net/wh211212/blog/column
本文地址:?http://www.linuxprobe.com/git-branch-history-today.html ?編輯:王輝,審核員:岳永
《Linux就該這么學》是由資深運維專家劉遄及全國多名紅帽架構師(RHCA)基于最新RHEL7系統共同編寫的高質量Linux技術自學教程,極其適合用于Linux技術入門教程或講課輔助教材。
? 劉遄老師QQ:5604241
? 學員助教QQ:5604674
? Linux技術交流A群(滿):560843
? Linux技術交流B群:340829
? Linux技術交流C群:463590
? 官方站點:www.linuxprobe.com
? 電腦在線閱讀效果更佳:
http://www.linuxprobe.com/chapter-00.html
按住圖片3秒,即可自動關注。
點擊左下角查看更多熱門技術
添加微信公眾號《Linux就該這么學》,掌握最新IT資訊動態,免費領取Linux課程以及專業的RHCE考前答疑服務。
《Linux就該這么學》在線免費閱讀地址:http://www.linuxprobe.com/
閱讀原文:http://blog.sina.com.cn/s/blog_1329eba300102wl73.html