【正文】
在版本回退里,你已經(jīng)知道,每次提交,Git都把它們串成一條時(shí)間線,這條時(shí)間線就是一個(gè)分支。截止到目前,只有一條時(shí)間線,在Git里,這個(gè)分支叫主分支,即master分支。HEAD嚴(yán)格來(lái)說(shuō)不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當(dāng)前分支。一開始的時(shí)候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當(dāng)前分支,以及當(dāng)前分支的提交點(diǎn):每次提交,master分支都會(huì)向前移動(dòng)一步,這樣,隨著你不斷提交,master分支的線也越來(lái)越長(zhǎng):當(dāng)我們創(chuàng)建新的分支,例如dev時(shí),Git新建了一個(gè)指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當(dāng)前分支在dev上:你看,Git創(chuàng)建一個(gè)分支很快,因?yàn)槌嗽黾右粋€(gè)dev指針,改改HEAD的指向,工作區(qū)的文件都沒(méi)有任何變化!不過(guò),從現(xiàn)在開始,對(duì)工作區(qū)的修改和提交就是針對(duì)dev分支了,比如新提交一次后,dev指針往前移動(dòng)一步,而master指針不變:假如我們?cè)赿ev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最簡(jiǎn)單的方法,就是直接把master指向dev的當(dāng)前提交,就完成了合并:所以Git合并分支也很快!就改改指針,工作區(qū)內(nèi)容也不變!合并完分支后,甚至可以刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉后,我們就剩下了一條master分支:真是太神奇了,你看得出來(lái)有些提交是通過(guò)分支完成的嗎?下面開始實(shí)戰(zhàn)。首先,我們創(chuàng)建dev分支,然后切換到dev分支:$ git checkout b devSwitched to a new branch 39。dev39。git checkout命令加上b參數(shù)表示創(chuàng)建并切換,相當(dāng)于以下兩條命令:$ git branch dev$ git checkout devSwitched to branch 39。dev39。然后,用git branch命令查看當(dāng)前分支:$ git branch* dev mastergit branch命令會(huì)列出所有分支,當(dāng)前分支前面會(huì)標(biāo)一個(gè)*號(hào)。然后,我們就可以在dev分支上正常提交,加上一行:Creating a new branch is quick.然后提交:$ git add $ git mit m branch test[dev fec145a] branch test 1 file changed, 1 insertion(+)現(xiàn)在,dev分支的工作完成,我們就可以切換回master分支:$ git checkout masterSwitched to branch 39。master39。切換回master分支后,剛才添加的內(nèi)容不見(jiàn)了!因?yàn)槟莻€(gè)提交是在dev分支上,而master分支此刻的提交點(diǎn)并沒(méi)有變:現(xiàn)在,我們把dev分支的工作成果合并到master分支上:$ git merge devUpdating d17efd8..fec145aFastforward | 1 + 1 file changed, 1 insertion(+)git merge命令用于合并指定分支到當(dāng)前分支。合并后,就可以看到,和dev分支的最新提交是完全一樣的。注意到上面的Fastforward信息,Git告訴我們,這次合并是“快進(jìn)模式”,也就是直接把master指向dev的當(dāng)前提交,所以合并速度非???。當(dāng)然,也不是每次合并都能Fastforward,我們后面會(huì)講其他方式的合并。合并完成后,就可以放心地刪除dev分支了:$ git branch d devDeleted branch dev (was fec145a).刪除后,查看branch,就只剩下master分支了:$ git branch* master因?yàn)閯?chuàng)建、合并和刪除分支非???,所以Git鼓勵(lì)你使用分支完成某個(gè)任務(wù),合并后再刪掉分支,這和直接在master分支上工作效果是一樣的,但過(guò)程更安全。小結(jié)Git鼓勵(lì)大量使用分支:查看分支:git branch創(chuàng)建分支:git branch name切換分支:git checkout name創(chuàng)建+切換分支:git checkout b name合并某分支到當(dāng)前分支:git merge name刪除分支:git branch d name解決沖突閱讀: 395815人生不如意之事十之八九,合并分支往往也不是一帆風(fēng)順的。準(zhǔn)備新的feature1分支,繼續(xù)我們的新分支開發(fā):$ git checkout b feature1Switched to a new branch 39。feature139。,改為:Creating a new branch is quick AND simple.在feature1分支上提交:$ git add $ git mit m AND simple[feature1 75a857c] AND simple 1 file changed, 1 insertion(+), 1 deletion()切換到master分支:$ git checkout masterSwitched to branch 39。master39。Your branch is ahead of 39。origin/master39。 by 1 mit.Git還會(huì)自動(dòng)提示我們當(dāng)前master分支比遠(yuǎn)程的master分支要超前1個(gè)提交。:Creating a new branch is quick amp。 simple.提交:$ git add $ git mit m amp。 simple[master 400b400] amp。 simple 1 file changed, 1 insertion(+), 1 deletion()現(xiàn)在,master分支和feature1分支各自都分別有新的提交,變成了這樣:這種情況下,Git無(wú)法執(zhí)行“快速合并”,只能試圖把各自的修改合并起來(lái),但這種合并就可能會(huì)有沖突,我們?cè)囋嚳矗? git merge feature1Automerging CONFLICT (content): Merge conflict in Automatic merge failed。 fix conflicts and then mit the result.果然沖突了!Git告訴我們,必須手動(dòng)解決沖突后再提交。git status也可以告訴我們沖突的文件:$ git status On branch master Your branch is ahead of 39。origin/master39。 by 2 mits. Unmerged paths: (use git add/rm file... as appropriate to mark resolution) both modified: no changes added to mit (use git add and/or git mit a):Git is a distributed version control system.Git is free software distributed under the GPL.Git has a mutable index called stage.Git tracks changes of files. HEADCreating a new branch is quick amp。 simple.=======Creating a new branch is quick AND simple. feature1Git用,=======,標(biāo)記出不同分支的內(nèi)容,我們修改如下后保存:Creating a new branch is quick and simple.再提交:$ git add $ git mit m conflict fixed[master 59bc1cb] conflict fixed現(xiàn)在,master分支和feature1分支變成了下圖所示:用帶參數(shù)的git log也可以看到分支的合并情況:$ git log graph pretty=oneline abbrevmit* 59bc1cb conflict fixed|\| * 75a857c AND simple* | 400b400 amp。 simple|/* fec145a branch test...最后,刪除feature1分支:$ git branch d feature1Deleted branch feature1 (was 75a857c).工作完成。小結(jié)當(dāng)Git無(wú)法自動(dòng)合并分支時(shí),就必須首先解決沖突。解決沖突后,再提交,合并完成。用git log graph命令可以看到分支合并圖。分支管理策略閱讀: 320666通常,合并分支時(shí),如果可能,Git會(huì)用Fast forward模式,但這種模式下,刪除分支后,會(huì)丟掉分支信息。如果要強(qiáng)制禁用Fast forward模式,Git就會(huì)在merge時(shí)生成一個(gè)新的mit,這樣,從分支歷史上就可以看出分支信息。下面我們實(shí)戰(zhàn)一下noff方式的git merge:首先,仍然創(chuàng)建并切換dev分支:$ git checkout b devSwitched to a new branch 39。dev39。,并提交一個(gè)新的mit:$ git add $ git mit m add merge[dev 6224937] add merge 1 file changed, 1 insertion(+)現(xiàn)在,我們切換回master:$ git checkout masterSwitched to branch 39。master39。準(zhǔn)備合并dev分支,請(qǐng)注意noff參數(shù),表示禁用Fast forward:$ git merge noff m merge with noff devMerge made by the 39。recursive39。 strategy. | 1 + 1 file changed, 1 insertion(+)因?yàn)楸敬魏喜⒁獎(jiǎng)?chuàng)建一個(gè)新的mit,所以加上m參數(shù),把mit描述寫進(jìn)去。合并后,我們用git log看看分支歷史:$ git log graph pretty=oneline abbrevmit* 7825a50 merge with noff|\| * 6224937 add merge|/* 59bc1cb conflict fixed...可以看到,不使用Fast forward模式,merge后就像這樣:分支策略在實(shí)際開發(fā)中,我們應(yīng)該按照幾個(gè)基本原則進(jìn)行分支管理:首先,master分支應(yīng)該是非常穩(wěn)定的,也就是僅用來(lái)發(fā)布新版本,平時(shí)不能在上面干活;那在哪干活呢?干活都在dev分支上,也就是說(shuō),dev分支是不穩(wěn)定的,到某個(gè)時(shí)候,再把dev分支合并到master上,;你和你的小伙伴們每個(gè)人都在dev分支上干活,每個(gè)人都有自己的分支,時(shí)不時(shí)地往dev分支上合并就可以了。所以,團(tuán)隊(duì)合作的分支看起來(lái)就像這樣:小結(jié)Git分支十分強(qiáng)大,在團(tuán)隊(duì)開發(fā)中應(yīng)該充分應(yīng)用。合并分支時(shí),加上noff參數(shù)就可以用普通模式合并,合并后的歷史有分支,能看出來(lái)曾經(jīng)做過(guò)合并,而fast forward合并就看不出來(lái)曾經(jīng)做過(guò)合并。Bug分支閱讀: 238078軟件開發(fā)中,bug就像家常便飯一樣。有了bug就需要修復(fù),在Git中,由于分支是如此的強(qiáng)大,所以,每個(gè)bug都可以通過(guò)一個(gè)新的臨時(shí)分支來(lái)修復(fù),修復(fù)后,合并分支,然后將臨時(shí)分支刪除。當(dāng)你接到一個(gè)修復(fù)一個(gè)代號(hào)101的bug的任務(wù)時(shí),很自然地,你想創(chuàng)建一個(gè)分支issue101來(lái)修復(fù)它,但是,等等,當(dāng)前正在dev上進(jìn)行的工作還沒(méi)有提交:$ git status On branch dev Changes to be mitted: (use git reset HEAD file... to unstage) new file: Changes not staged for mit: (use git add file... to update what will be mitted) (use git checkout file... to discard changes in working directory) modified: 并不是你不想提交,而是工作只進(jìn)行到一半,還沒(méi)法提交,預(yù)計(jì)完成還需1天時(shí)間。但是,必須在兩個(gè)小時(shí)內(nèi)修復(fù)該bug,怎么辦?幸好,Git還提供了一個(gè)stash功能,可以把當(dāng)前工作現(xiàn)場(chǎng)“儲(chǔ)藏”起來(lái),等以后恢復(fù)現(xiàn)場(chǎng)后繼續(xù)工作:$ git stashSaved working directory and index state WIP on dev: 6224937 add mergeHEAD is now at 6224937 add merge現(xiàn)在,用git status查看工作區(qū),就是干凈的(除非有沒(méi)有被Git