分支和合併的基本用法 - Git SCM
文章推薦指數: 80 %
3.2 使用Git 分支- 分支和合併的基本用法. 分支和合併的基本用法. 讓我們來看一個你在現實生活中,有可能會用到的分支(branch)與合併(merge)工作流程的簡單範例, ...
About
BranchingandMerging
SmallandFast
Distributed
DataAssurance
StagingArea
FreeandOpenSource
Trademark
Documentation
Reference
Book
Videos
ExternalLinks
Downloads
GUIClients
Logos
Community
Thisbookisavailablein
English.
Fulltranslationavailablein
azərbaycandili,
българскиезик,
Deutsch,
Español,
Français,
Ελληνικά,
日本語,
한국어,
Nederlands,
Русский,
Slovenščina,
Tagalog,
Українська
简体中文,
Partialtranslationsavailablein
Čeština,
Македонски,
Polski,
Српски,
Ўзбекча,
繁體中文,
Translationsstartedfor
Беларуская,
فارسی,
Indonesian,
Italiano,
BahasaMelayu,
Português(Brasil),
Português(Portugal),
Svenska,
Türkçe.
ThesourceofthisbookishostedonGitHub.
Patches,suggestionsandcommentsarewelcome.
Chapters▾
1.開始
1.1
關於版本控制
1.2
Git的簡史
1.3
Git基礎要點
1.4
命令列
1.5
Git安裝教學
1.6
初次設定Git
1.7
取得說明文件
1.8
摘要
2.Git基礎
2.1
取得一個Git倉儲
2.2
紀錄變更到版本庫中
2.3
檢視提交的歷史記錄
2.4
復原
2.5
與遠端協同工作
2.6
標籤
2.7
GitAliases
2.8
總結
3.使用Git分支
3.1
簡述分支
3.2
分支和合併的基本用法
3.3
分支管理
3.4
分支工作流程
3.5
遠端分支
3.6
衍合
3.7
總結
4.伺服器上的Git
4.1
通訊協定
4.2
在伺服器上佈署Git
4.3
產生你的SSH公鑰
4.4
設定伺服器
4.5
Git常駐程式
4.6
SmartHTTP
4.7
GitWeb
4.8
GitLab
4.9
第3方Git託管方案
4.10
總結
5.分散式的Git
5.1
分散式工作流程
5.2
對專案進行貢獻
5.3
維護一個專案
5.4
Summary
6.GitHub
6.1
建立帳戶及設定
6.2
參與一個專案
6.3
維護專案
6.4
Managinganorganization
6.5
ScriptingGitHub
6.6
總結
7.Git工具
7.1
RevisionSelection
7.2
InteractiveStaging
7.3
StashingandCleaning
7.4
SigningYourWork
7.5
Searching
7.6
RewritingHistory
7.7
ResetDemystified
7.8
AdvancedMerging
7.9
Rerere
7.10
DebuggingwithGit
7.11
Submodules
7.12
Bundling
7.13
Replace
7.14
CredentialStorage
7.15
總結
8.CustomizingGit
8.1
GitConfiguration
8.2
GitAttributes
8.3
GitHooks
8.4
AnExampleGit-EnforcedPolicy
8.5
Summary
9.GitandOtherSystems
9.1
GitasaClient
9.2
MigratingtoGit
9.3
Summary
10.GitInternals
10.1
PlumbingandPorcelain
10.2
GitObjects
10.3
GitReferences
10.4
Packfiles
10.5
TheRefspec
10.6
TransferProtocols
10.7
MaintenanceandDataRecovery
10.8
EnvironmentVariables
10.9
Summary
A1.附錄A:GitinOtherEnvironments
A1.1
GraphicalInterfaces
A1.2
GitinVisualStudio
A1.3
GitinEclipse
A1.4
GitinBash
A1.5
GitinZsh
A1.6
GitinPowershell
A1.7
Summary
A2.附錄B:EmbeddingGitinyourApplications
A2.1
Command-lineGit
A2.2
Libgit2
A2.3
JGit
A3.附錄C:GitCommands
A3.1
SetupandConfig
A3.2
GettingandCreatingProjects
A3.3
BasicSnapshotting
A3.4
BranchingandMerging
A3.5
SharingandUpdatingProjects
A3.6
InspectionandComparison
A3.7
Debugging
A3.8
Patching
A3.9
Email
A3.10
ExternalSystems
A3.11
Administration
A3.12
PlumbingCommands
2ndEdition
3.2使用Git分支-分支和合併的基本用法
分支和合併的基本用法
讓我們來看一個你在現實生活中,有可能會用到的分支(branch)與合併(merge)工作流程的簡單範例,
你做了以下動作:
開發一個網站。
建立一個分支以實現一個新故事。
在這個分支上進行開發。
此時你接到一個電話,有個很危急的問題需要緊急修正(hotfix),
你可以按照下面的方式處理:
切換到發佈產品用的分支。
在同一個提交上建立一個新分支,在這個分支上修正問題。
通過測試後,切回發佈產品用的分支,將修正用的分支合併進來,然後再推送(push)出去以發佈產品。
切換到之前實現新需求的分支以繼續工作。
分支的基本用法
首先,我們假設你正在開發你的專案,並且已經有一些提交(commit)了。
圖表18.一個簡單的提交歷史
無論你的公司使用的議題追蹤系統(issue-trackingsystem)是哪一套,你決定要修正其中的議題#53;
要同時新建並切換到新分支,你可以在執行gitcheckout時加上-b選項:
$gitcheckout-biss53
Switchedtoanewbranch"iss53"
它相當於下面這兩條命令:
$gitbranchiss53
$gitcheckoutiss53
圖表19.建立一個新分支指標
你開始開發網站,並做了一些提交;
因為你檢出(checkout)了這個分支(也就是HEAD指標正指向它),iss53分支也隨之向前推進:
$vimindex.html
$gitcommit-a-m'addedanewfooter[issue53]'
圖表20.分支iss53會隨工作進展向前推進
現在你接到電話,那個網站有一個問題需要立即修正;
有了Git,你就不用把你的緊急修正連同iss53尚未完成的內容一起部署(deploy)到正式環境;你也不用為了正確地套用修正而先花一大堆功夫回復之前iss53的修改;
唯一需要做的只是切換回發佈產品用的master分支。
然而,在切換分支之前,留意一下你的工作目錄或預存區(stagingarea)裡是否有還沒提交的內容,它可能會和你即要檢出的分支產生衝突(conflict),Git會因此而不讓你切換分支;
所以切換分支的時候最好先保持一個乾淨的工作區域。
稍後會在StashingandCleaning中介紹幾個繞過這種問題的辦法(分別叫做「使用收藏(stashing)」和「提交的修訂方法(commitamending)」)。
目前先讓我們假設你已經提交了所有的變更,因此你可以切回master分支了:
$gitcheckoutmaster
Switchedtobranch'master'
此時工作目錄中的內容和你在解決問題#53之前的內容一模一樣,你可以集中精力進行緊急修正了;
很重要的一點需要牢記:當你切換分支時,Git會重置(reset)工作目錄內容,就像回到你在這個分支最後一次提交後的內容,
它會自動地增加、刪除和修改檔案以確保工作目錄的內容和當時的內容完全一樣。
接下來開始緊急修正;
讓我們建立一個緊急修正用的分支來進行工作,直到完成它:
$gitcheckout-bhotfix
Switchedtoanewbranch'hotfix'
$vimindex.html
$gitcommit-a-m'fixedthebrokenemailaddress'
[hotfix1fb7853]fixedthebrokenemailaddress
1filechanged,2insertions(+)
圖表21.基於master的緊急修正分支
你可以跑一些測試以確保該修正是你想要的,然後切回master分支並把它合併進來,再部署到產品上;
用gitmerge命令來進行合併:
$gitcheckoutmaster
$gitmergehotfix
Updatingf42c576..3a0874c
Fast-forward
index.html|2++
1filechanged,2insertions(+)
注意合併時有一個「Fast-forward」字眼;
由於你要合併的分支hotfix所指向的提交C4直接超前了提交C2,Git於是簡單地把分支指標向前推進;
換句話說,如果想要合併的提交可以直接往回追溯歷史到目前所在的提交,Git會因為沒有需要合併的工作而簡單地把指標向前推進——這就是所謂的「快進(fast-forward)」。
現在你的修改已經含在master分支所指向的提交的快照中,你可以部署該修正了。
圖表22.master被快進到hotfix
在那個超級重要的修正被部署以後,你準備要切回到之前被中斷而正在做的工作;
然而在那之前,你可以先刪除hotfix,因為你不再需要它了——master也指向相同的提交;
使用gitbranch的-d選項執行刪除操作:
$gitbranch-dhotfix
Deletedbranchhotfix(3a0874c).
現在你可以切回到之前用來解決議題#53且仍在進展中的分支以繼續工作:
$gitcheckoutiss53
Switchedtobranch"iss53"
$vimindex.html
$gitcommit-a-m'finishedthenewfooter[issue53]'
[iss53ad82d7a]finishedthenewfooter[issue53]
1filechanged,1insertion(+)
圖表23.繼續在分支iss53上工作
這裡值得注意的是之前hotfix分支的修改內容尚未包含到iss53分支的檔案中;
如果需要納入那個修正,你可以用gitmergemaster把master分支合併到iss53分支;或者等iss53分支完成之後,再將它合併到master。
合併的基本用法
你已經完成了議題#53的工作,並準備好將它合併到master分支;
要完成這件事,你需要將iss53分支合併到master分支,實際操作和之前合併hotfix分支時差不多,
只需切回合併目的地的master分支,然後執行gitmerge命令:
$gitcheckoutmaster
Switchedtobranch'master'
$gitmergeiss53
Mergemadebythe'recursive'strategy.
index.html|1+
1filechanged,1insertion(+)
這次的合併和之前合併hotfix的情況看起來有點不一樣;
在這種情況下,你的開發歷史是從一個較早的點便開始分離開來,
由於目前所在的提交(譯註:C4)並不是被合併的分支(譯註:iss53,它指向C5)的直接祖先,Git必需進行一些處理;
就此例而言,Git會用兩個分支末端的快照(譯註:C4、C5)以及它們的共同祖先(譯註:C2)進行一次簡單的三方合併(three-waymerge)。
圖表24.典型的合併會用到的三個快照
不同於將分支指標向前推進,Git會對三方合併後的結果產生一個新的快照,並自動建立一個指向這個快照的提交(譯註:C6)。
這個提交被稱為「合併提交(mergecommit)」,特別的是它的親代(parent)超過一個(譯註:C4和C5)。
圖表25.一個合併提交
值得一提的是Git會決定哪個共同祖先才是最佳合併基準;這一點和一些較舊的版控工具有所不同,像是CVS或Subversion(1.5以前的版本),它們需要開發者自己手動找出最佳合併基準;
這讓Git的合併操作比起其他系統都要簡單許多。
既然你的工作成果已經合併了,也就不再需要iss53分支了,
你可以在議題追蹤系統中關閉該議題,然後刪除這個分支:
$gitbranch-diss53
合併衝突的基本解法
有時候合併過程並不會如此順利,
如果在不同的分支中都修改了同一個檔案的同一部分,Git就無法乾淨地合併它們;
如果你在解決議題#53的過程中修改了hotfix中也修改過的部分,將得到類似下面的「合併衝突」結果:
$gitmergeiss53
Auto-mergingindex.html
CONFLICT(content):Mergeconflictinindex.html
Automaticmergefailed;fixconflictsandthencommittheresult.
Git沒有自動產生新的合併提交,
它會暫停下來等你解決(resolve)衝突;
在合併衝突發生後的任何時候,如果你要看看哪些檔案還沒有合併,可以使用gitstatus:
$gitstatus
Onbranchmaster
Youhaveunmergedpaths.
(fixconflictsandrun"gitcommit")
Unmergedpaths:
(use"gitadd
在解決了每個衝突檔案裡的每個衝突後,對每個檔案執行gitadd會將它們標記為已解決狀態,
因為預存(stage)動作代表了衝突已經解決。
如果你想用圖形介面的工具來解決這些衝突,你可以執行gitmergetool,它會呼叫一個適當的視覺化合併工具並引導你解決衝突:
$gitmergetool
Thismessageisdisplayedbecause'merge.tool'isnotconfigured.
See'gitmergetool--tool-help'or'githelpconfig'formoredetails.
'gitmergetool'willnowattempttouseoneofthefollowingtools:
opendiffkdiff3tkdiffxxdiffmeldtortoisemergegvimdiffdiffusediffmergeecmergep4mergearaxisbc3codecomparevimdiffemerge
Merging:
index.html
Normalmergeconflictfor'index.html':
{local}:modifiedfile
{remote}:modifiedfile
Hitreturntostartmergeresolutiontool(opendiff):
如果不想用預設的合併工具(因為在Mac上執行了該命令,Git預設選擇了opendiff),你可以在「oneofthefollowingtools」列表中找到可使用的合併工具,
然後只要輸入你想使用的工具名稱即可。
筆記
如果你需要更多進階的工具用來解決刁鑽的合併衝突,我們將在AdvancedMerging介紹更多合併操作方法。
退出合併工具以後,Git會詢問你合併是否成功,
如果回答「是」,它會幫你把相關檔案預存起來,將狀態標記為已解決;
你可以再次執行gitstatus來確認所有衝突都已經解決:
$gitstatus
Onbranchmaster
Allconflictsfixedbutyouarestillmerging.
(use"gitcommit"toconcludemerge)
Changestobecommitted:
modified:index.html
如果你滿意這個結果,並且確認了所有衝突都已經解決也預存了,就可以用gitcommit來完成這次合併提交;
預設的提交訊息看起來像這樣:
Mergebranch'iss53'
Conflicts:
index.html
#
#Itlookslikeyoumaybecommittingamerge.
#Ifthisisnotcorrect,pleaseremovethefile
# .git/MERGE_HEAD
#andtryagain.
#Pleaseenterthecommitmessageforyourchanges.Linesstarting
#with'#'willbeignored,andanemptymessageabortsthecommit.
#Onbranchmaster
#Allconflictsfixedbutyouarestillmerging.
#
#Changestobecommitted:
# modified:index.html
#
如果解決衝突的理由不是那麼明顯,或是想要幫助將來的人理解為何你要這樣解決衝突,你可以在訊息中提供更多的細節來說明。
prev|next
延伸文章資訊
- 1合併分支【分支】 | 連猴子都能懂的Git入門指南 - Backlog
Merge. 使用merge,可以合併多個歷史記錄。 如下圖所示bugfix 分支是從master 分支分開出來的。 分支.
- 2git merge最简洁用法_zl1zl2zl3的博客
一、开发分支(dev)上的代码达到上线的标准后,要合并到master 分支git checkout devgit pullgit checkout mastergit merge devgit ...
- 3git merge最簡潔用法詳解 - 程式人生
git merge 是在Git 中使用比較頻繁的一個命令,其主要用於將兩個或兩個以上的開發歷史加入(合併)一起。本文就為大家帶來git merge 命令的常見用法。
- 4[Git教學] 分支合併: merge 與rebase 差異 - MAX行銷誌
在使用merge 合併分支的時候,git 預設會以fast-forward 的模式進行,那 ... 主分支$ git checkout master # 使用fast-forward $ git...
- 5Git merge && git rebase的用法- 浅浅念- 博客园