git分支的合并
原文:?? http://gitbook.liuhui998.com/3_3.html http://gitbook.liuhui998.com/5_3.html 一、如何分支的合并 在git中,可以使用git merge?和git rebase兩個(gè)命令來(lái)進(jìn)行分支的合并。 git merge?和git rebase在大體上都差不多,下文主要以git merge來(lái)例來(lái)講解分支的合并流程。 如果你想了解分支合并的更多內(nèi)容,請(qǐng)閱讀《git merge簡(jiǎn)介》,《git rebase簡(jiǎn)介(基本篇)》和《git rebase簡(jiǎn)介(高級(jí)篇)》。 git merge命令示例: $?git?merge?branchname 這個(gè)命令把分支"branchname"合并到了當(dāng)前分支里面。 如有沖突(沖突--同一個(gè)文件在遠(yuǎn)程分支和本地分支里按不同的方式被修改了);那么命令的執(zhí)行輸出就像下面一樣 $?git?merge?next 100% (4/4) done Auto-merged file.txt CONFLICT (content): Merge conflict in file.txt Automatic merge failed; fix conflicts and then commit the result. 在有問題的文件上會(huì)有沖突標(biāo)記,在你手動(dòng)解決完沖突后就可以把此文件添 加到索引(index)中去,用git commit命令來(lái)提交,就像平時(shí)修改了一個(gè)文件 一樣。 如果你用gitk來(lái)查看commit的結(jié)果,你會(huì)看到它有兩個(gè)父分支:一個(gè)指向當(dāng)前的分支,另外一個(gè)指向剛才合并進(jìn)來(lái)的分支。 二、解決合并中的沖突 如果執(zhí)行自動(dòng)合并沒有成功的話,git會(huì)在索引和工作樹里設(shè)置一個(gè)特殊的狀態(tài), 提示你如何解決合并中出現(xiàn)的沖突。 有沖突(conflicts)的文件會(huì)保存在索引中,除非你解決了問題了并且更新了索引,否則執(zhí)行 git commit都會(huì)失敗: $?git?commit file.txt: needs merge 如果執(zhí)行?git status?會(huì)顯示這些文件沒有合并(unmerged),這些有沖突的文件里面會(huì)添加像下面的沖突標(biāo)識(shí)符: <<<<<<< HEAD:file.txt Hello world ======= Goodbye >>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt 你所需要的做是就是編輯解決沖突,(接著把沖突標(biāo)識(shí)符刪掉),再執(zhí)行下面的命令: $ git add file.txt $ git commit 注意:提交注釋里已經(jīng)有一些關(guān)于合并的信息了,通常是用這些默認(rèn)信息,但是你可以添加一些你想要的注釋。 上面這些就是你要做一個(gè)簡(jiǎn)單合并所要知道的,但是git提供更多的一些信息來(lái) 幫助解決沖突。 三、撒銷一個(gè)合并 如果你覺得你合并后的狀態(tài)是一團(tuán)亂麻,想把當(dāng)前的修改都放棄,你可以用下面的命令回到合并之前的狀態(tài): $?git?reset?--hard?HEAD 或者你已經(jīng)把合并后的代碼提交,但還是想把它們?nèi)鲣N: $?git?reset?--hard?ORIG_HEAD 但是剛才這條命令在某些情況會(huì)很危險(xiǎn),如果你把一個(gè)已經(jīng)被另一個(gè)分支合并的分支給刪了,那么 以后在合并相關(guān)的分支時(shí)會(huì)出錯(cuò)。 關(guān)于撤銷的更多內(nèi)容請(qǐng)參考《git reset簡(jiǎn)介》 四、快速向前合并 還有一種需要特殊對(duì)待的情況,在前面沒有提到。通常,一個(gè)合并會(huì)產(chǎn)生一個(gè)合并提交(commit), 把兩個(gè)父分支里的每一行內(nèi)容都合并進(jìn)來(lái)。 但是,如果當(dāng)前的分支和另一個(gè)分支沒有內(nèi)容上的差異,就是說(shuō)當(dāng)前分支的每一個(gè)提交(commit)都已經(jīng)存在另一個(gè)分支里了,git 就會(huì)執(zhí)行一個(gè)“快速向前"(fast forward)操作;git 不創(chuàng)建任何新的提交(commit),只是將當(dāng)前分支指向合并進(jìn)來(lái)的分支。 五、在合并過程中得到解決沖突的協(xié)助 git會(huì)把所有可以自動(dòng)合并的修改加入到索引中去, 所以git diff只會(huì)顯示有沖突的部分. 它使用了一種不常見的語(yǔ)法: $?git?diff diff --cc file.txt index 802992c,2b60207..0000000 --- a/file.txt +++ b/file.txt @@@ -1,1 -1,1 +1,5 @@@ ++<<<<<<< HEAD:file.txt +Hello world ++======= + Goodbye ++>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt 回憶一下, 在我們解決沖突之后, 得到的提交會(huì)有兩個(gè)而不是一個(gè)父提交:?一個(gè)父提交是當(dāng)前分支提交前的HEAD,; 另外一個(gè)父提交是被合并分支的HEAD, 被暫時(shí)存在MERGE_HEAD. 在合并過程中, 索引中保存著每個(gè)文件的三個(gè)版本. 三個(gè)"文件暫存(file stage)"中的每一個(gè)都代表了文件的不同版本: $ git show :1:file.txt ?# 兩個(gè)分支共同祖先中的版本. $ git show :2:file.txt??# HEAD中的版本. $ git show :3:file.txt ?# MERGE_HEAD中的版本. 當(dāng)你使用git diff去顯示沖突時(shí), 它在工作樹(work tree),?暫存2(stage 2)和暫存3(stage 3)之間執(zhí)行三路diff操作, 只顯示那些兩方都有的塊(換句話說(shuō), 當(dāng)一個(gè)塊的合并結(jié)果只從暫存2中得到時(shí), 是不會(huì)被顯示出來(lái)的; 對(duì)于暫存3來(lái)說(shuō)也是一樣). 上面的diff結(jié)果顯示了file.txt在工作樹, 暫存2和暫存3中的差異.?git不在每行前面加上單個(gè)'+'或者'-', 相反地, 它使用兩欄去顯示差異: 第一欄用于顯示第一個(gè)父提交與工作目錄文件拷貝的差異, 第二欄用于顯示第二個(gè)父提交與工作文件拷貝的差異.?(參見git diff-files中的"COMBINED DIFF FORMAT"取得此格式詳細(xì)信息.) 在用直觀的方法解決沖突之后(但是在更新索引之前), diff輸出會(huì)變成下面的樣子: $?git diff diff --cc file.txt index 802992c,2b60207..0000000 --- a/file.txt +++ b/file.txt @@@ -1,1 -1,1 +1,1 @@@ - Hello world -Goodbye ++Goodbye world 上面的輸出顯示了解決沖突后的版本刪除了第一個(gè)父版本提供的"Hello world"和第二個(gè)父版本提供的"Goodbye", 然后加入了兩個(gè)父版本中都沒有的"Goodbye world". 一些特別diff選項(xiàng)允許你對(duì)比工作目錄和三個(gè)暫存中任何一個(gè)的差異: $ git diff -1 file.txt ? ???# 與暫存1進(jìn)行比較 $ git diff --base file.txt ? ? ? ???# 與上相同 $ git diff -2 file.txt ? ???# 與暫存2進(jìn)行比較 $ git diff --ours file.txt ? ? ? ? ?# 與上相同 $ git diff -3 file.txt ? ???# 與暫存3進(jìn)行比較 $ git diff --theirs file.txt ? ?# 與上相同. 還有,git log和gitk命令也為合并操作提供了特別的協(xié)助: $?git log?--merge $?gitk?--merge 這會(huì)顯示所有那些只在HEAD或者只在MERGE_HEAD中存在的提交, 還有那些更新(touch)了未合并文件的提交. 你也可以使用git mergetool, 它允許你使用外部工具如emacs或kdiff3去合并文件. 每次你解決沖突之后, 應(yīng)該更新索引: $?git add?file.txt 完成索引更新之后, git-diff(缺省地)不再顯示那個(gè)文件的差異, 所以那個(gè)文件的不同暫存版本會(huì)被"折疊"起來(lái). 六、多路合并 你可以一次合并多個(gè)頭, 只需簡(jiǎn)單地把它們作為git merge的參數(shù)列出. 例如, $ git merge scott/master rick/master tom/master 相當(dāng)于: $ git merge scott/master $ git merge rick/master $ git merge tom/master 七、子樹 有時(shí)會(huì)出現(xiàn)你想在自己項(xiàng)目中引入其他獨(dú)立開發(fā)項(xiàng)目的內(nèi)容的情況. 在沒有路徑?jīng)_突的前提下, 你只需要簡(jiǎn)單地從其他項(xiàng)目拉取內(nèi)容即可. 如果有沖突的文件, 那么就會(huì)出現(xiàn)問題. 可能的例子包括Makefile和其他一些標(biāo)準(zhǔn)文件名. 你可以選擇合并這些沖突的文件, 但是更多的情況是你不愿意把它們合并. 一個(gè)更好解決方案是把外部項(xiàng)目作為一個(gè)子目錄進(jìn)行合并. 這種情況不被遞歸合并策略所支持, 所以簡(jiǎn)單的拉取是無(wú)用的. 在這種情況下, 你需要的是子樹合并策略. 這下面例子中, 我們?cè)O(shè)定你有一個(gè)倉(cāng)庫(kù)位于/path/to/B (如果你需要的話, 也可以是一個(gè)URL). 你想要合并那個(gè)倉(cāng)庫(kù)的master分支到你當(dāng)前倉(cāng)庫(kù)的dir-B子目錄下. 下面就是你所需要的命令序列: $ git remote add -f Bproject /path/to/B (1) $ git merge -s ours --no-commit Bproject/master (2) $ git read-tree --prefix=dir-B/ -u Bproject/master (3) $ git commit -m "Merge B project as our subdirectory" (4) $ git pull -s subtree Bproject master (5) 子樹合并的好處就是它并沒有給你倉(cāng)庫(kù)的用戶增加太多的管理負(fù)擔(dān). 它兼容于較老(版本號(hào)小于1.5.2)的客戶端, 克隆完成之后馬上可以得到代碼. 然而, 如果你使用子模塊(submodule), 你可以選擇不傳輸這些子模塊對(duì)象. 這可能在子樹合并過程中造成問題. 譯者注: submodule是Git的另一種將別的倉(cāng)庫(kù)嵌入到本地倉(cāng)庫(kù)方法. 另外, 若你需要修改內(nèi)嵌外部項(xiàng)目的內(nèi)容, 使用子模塊方式可以更容易地提交你的修改.
轉(zhuǎn)載于:https://www.cnblogs.com/xingzc/p/5987026.html
總結(jié)
- 上一篇: 绝地求生现在多少钱
- 下一篇: html-css实例