您好,登錄后才能下訂單哦!
這篇“git中merge的知識(shí)點(diǎn)有哪些”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“git中merge的知識(shí)點(diǎn)有哪些”文章吧。
在git-merge命令中,有以下三種使用參數(shù):
git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]
git merge <msg> HEAD <commit>...
git merge --abort
git-merge命令是用于從指定的commit(s)合并到當(dāng)前分支的操作。
注:這里的指定commit(s)是指從這些歷史commit節(jié)點(diǎn)開始,一直到當(dāng)前分開的時(shí)候。
git-merge命令有以下兩種用途:
用于git-pull中,來整合另一代碼倉庫中的變化(即:git pull = git fetch + git merge)
用于從一個(gè)分支到另一個(gè)分支的合并
那么git merge topic
命令將會(huì)把在master分支上二者共同的節(jié)點(diǎn)(E節(jié)點(diǎn))之后分離的節(jié)點(diǎn)(即topic分支的A B C節(jié)點(diǎn))重現(xiàn)在master分支上,直到topic分支當(dāng)前的commit節(jié)點(diǎn)(C節(jié)點(diǎn)),并位于master分支的頂部。并且沿著master分支和topic分支創(chuàng)建一個(gè)記錄合并結(jié)果的新節(jié)點(diǎn),該節(jié)點(diǎn)帶有用戶描述合并變化的信息。
git merge <msg> HEAD <commit>...
命令該命令的存在是由于歷史原因,在新版本中不應(yīng)該使用它,應(yīng)該使用git merge -m <msg> <commit>....
進(jìn)行替代
git merge --abort
命令該命令僅僅在合并后導(dǎo)致沖突時(shí)才使用。git merge --abort
將會(huì)拋棄合并過程并且嘗試重建合并前的狀態(tài)。但是,當(dāng)合并開始時(shí)如果存在未commit的文件,git merge --abort
在某些情況下將無法重現(xiàn)合并前的狀態(tài)。(特別是這些未commit的文件在合并的過程中將會(huì)被修改時(shí))
警告:運(yùn)行
git-merge
時(shí)含有大量的未commit文件很容易讓你陷入困境,這將使你在沖突中難以回退。因此非常不鼓勵(lì)在使用git-merge
時(shí)存在未commit的文件,建議使用git-stash
命令將這些未commit文件暫存起來,并在解決沖突以后使用git stash pop
把這些未commit文件還原出來。
本部分用于介紹git-merge
命令中使用的參數(shù)
--commit
和--no-commit
--commit
參數(shù)使得合并后產(chǎn)生一個(gè)合并結(jié)果的commit節(jié)點(diǎn)。該參數(shù)可以覆蓋--no-commit
。--no-commit
參數(shù)使得合并后,為了防止合并失敗并不自動(dòng)提交,能夠給使用者一個(gè)機(jī)會(huì)在提交前審視和修改合并結(jié)果。
--edit
和-e
以及--no-edit
--edit
和-e
用于在成功合并、提交前調(diào)用編輯器來進(jìn)一步編輯自動(dòng)生成的合并信息。因此使用者能夠進(jìn)一步解釋和判斷合并的結(jié)果。--no-edit
參數(shù)能夠用于接受自動(dòng)合并的信息(通常情況下并不鼓勵(lì)這樣做)。
如果你在合并時(shí)已經(jīng)給定了
-m
參數(shù)(下文介紹),使用--edit
(或-e
)依然是有用的,這將在編輯器中進(jìn)一步編輯-m
所含的內(nèi)容。
舊版本的節(jié)點(diǎn)可能并不允許用戶去編輯合并日志信息。
--ff
命令--ff
是指fast-forward命令。當(dāng)使用fast-forward模式進(jìn)行合并時(shí),將不會(huì)創(chuàng)造一個(gè)新的commit節(jié)點(diǎn)。默認(rèn)情況下,git-merge
采用fast-forward模式。
關(guān)于fast-forward模式的詳細(xì)解釋,請(qǐng)看我的另一篇文章:一個(gè)成功的Git分支模型的“關(guān)于fast forward”一節(jié)。
--no-ff
命令即使可以使用fast-forward模式,也要?jiǎng)?chuàng)建一個(gè)新的合并節(jié)點(diǎn)。這是當(dāng)git merge
在合并一個(gè)tag時(shí)的默認(rèn)行為。
--ff-only
命令除非當(dāng)前HEAD節(jié)點(diǎn)已經(jīng)up-to-date(更新指向到最新節(jié)點(diǎn))或者能夠使用fast-forward模式進(jìn)行合并,否則的話將拒絕合并,并返回一個(gè)失敗狀態(tài)。
--log[=<n>]
和 --no-log
--log[=<n>]
將在合并提交時(shí),除了含有分支名以外,還將含有最多n個(gè)被合并commit節(jié)點(diǎn)的日志信息。--no-log
并不會(huì)列出該信息。
--stat
, -n
, --no-stat
命令--stat
參數(shù)將會(huì)在合并結(jié)果的末端顯示文件差異的狀態(tài)。文件差異的狀態(tài)也可以在git配置文件中的merge.stat配置。
相反,-n
, --no-stat
參數(shù)將不會(huì)顯示該信息。
--squash
和--no-squash
--squash
當(dāng)一個(gè)合并發(fā)生時(shí),從當(dāng)前分支和對(duì)方分支的共同祖先節(jié)點(diǎn)之后的對(duì)方分支節(jié)點(diǎn),一直到對(duì)方分支的頂部節(jié)點(diǎn)將會(huì)壓縮在一起,使用者可以經(jīng)過審視后進(jìn)行提交,產(chǎn)生一個(gè)新的節(jié)點(diǎn)。
注意1:該參數(shù)和
--no-ff
沖突
注意2:該參數(shù)使用后的結(jié)果類似于在當(dāng)前分支提交一個(gè)新節(jié)點(diǎn)。在某些情況下這個(gè)參數(shù)非常有用,例如使用Git Flow時(shí)(關(guān)于Git Flow,請(qǐng)參考:一個(gè)成功的Git分支模型),功能分支在進(jìn)行一個(gè)功能需求的研發(fā)時(shí),開發(fā)者可能在本地提交了大量且無意義的節(jié)點(diǎn),當(dāng)需要合并到develop分支時(shí),可能僅僅需要用一個(gè)新的節(jié)點(diǎn)來表示這一長串節(jié)點(diǎn)的修改內(nèi)容,這時(shí)
--squash
命令將會(huì)發(fā)揮作用。此外,如果功能分支的多次提交并不是瑣碎而都是有意義的,使用--no-ff
命令更為合適。--no-squash
的作用正好相反。
-s <strategy>
和 --strategy=<strategy>
-s <strategy>
和 --strategy=<strategy>
用于指定合并的策略。默認(rèn)情況如果沒有指定該參數(shù),git將按照下列情況采用默認(rèn)的合并策略:
合并節(jié)點(diǎn)只含有單個(gè)父節(jié)點(diǎn)時(shí)(如采用fast-forward模式時(shí)),采用recursive策略(下文介紹)。
合并節(jié)點(diǎn)含有多個(gè)父節(jié)點(diǎn)時(shí)(如采用no-fast-forward模式時(shí)),采用octopus策略(下文介紹)。
-X <option>
和 --strategy-option=<option>
在-s <strategy>
時(shí)指定該策略的具體參數(shù)(下文介紹)。
--verify-signatures
, --no-verify-signatures
用于驗(yàn)證被合并的節(jié)點(diǎn)是否帶有GPG簽名,并在合并中忽略那些不帶有GPG簽名驗(yàn)證的節(jié)點(diǎn)。
(以下引用摘自一篇轉(zhuǎn)載的文章,由于我沒有找到原作者,因此無法提供原作者信息和原文鏈接,如果有所侵權(quán)請(qǐng)私信或者評(píng)論告知,我將刪除以下引用內(nèi)容。)
GPG是加密軟件,可以使用GPG生成的公鑰在網(wǎng)上安全的傳播你的文件、代碼。
為什么說安全的?以Google所開發(fā)的repo為例,repo即采用GPG驗(yàn)證的方式,每個(gè)里程碑tag都帶有GPG加密驗(yàn)證,假如在里程碑v1.12.3處你想要做修改,修改完后將這個(gè)tag刪除,然后又創(chuàng)建同名tag指向你的修改點(diǎn),這必然是可以的。但是,在你再次clone你修改后的項(xiàng)目時(shí),你會(huì)發(fā)現(xiàn),你對(duì)此里程碑tag的改變不被認(rèn)可,驗(yàn)證失敗,導(dǎo)致你的修改在這里無法正常實(shí)現(xiàn)。這就是GPG驗(yàn)證的作用,這樣就能夠保證項(xiàng)目作者(私鑰持有者)所制定的里程碑別人將無法修改。那么,就可以說,作者的代碼是安全傳播的。
為什么會(huì)有這種需求?一個(gè)項(xiàng)目從開發(fā)到發(fā)布,再到后期的更新迭代,一定會(huì)存在若干的穩(wěn)定版本與開發(fā)版本(存在不穩(wěn)定因素)。作為項(xiàng)目發(fā)起者、持有者,有權(quán)定義他(們)所認(rèn)可的穩(wěn)定版本,這個(gè)穩(wěn)定版本,將不允許其他開發(fā)者進(jìn)行改動(dòng)。還以Google的repo項(xiàng)目為例,項(xiàng)目所有者定義項(xiàng)目開發(fā)過程中的點(diǎn)A為穩(wěn)定版v1.12.3,那么用戶在下載v1.12.3版本后,使用的肯定是A點(diǎn)所生成的項(xiàng)目、產(chǎn)品,就算其他開發(fā)者能夠在本地對(duì)v1.12.3進(jìn)行重新指定,指定到他們修改后的B點(diǎn),但是最終修改后的版本給用戶用的時(shí)候,會(huì)出現(xiàn)GPG簽名驗(yàn)證不通過的問題,也就是說這樣的修改是不生效的。
—summary
,--no-summary
和--stat
與 --no-stat
相似,并將在未來版本移除。
-q
和 --quiet
靜默操作,不顯示合并進(jìn)度信息。
-v
和 --verbose
顯示詳細(xì)的合并結(jié)果信息。
--progress
和 --no-progress
切換是否顯示合并的進(jìn)度信息。如果二者都沒有指定,那么在標(biāo)準(zhǔn)錯(cuò)誤發(fā)生時(shí),將在連接的終端顯示信息。請(qǐng)注意,并不是所有的合并策略都支持進(jìn)度報(bào)告。
-S[<keyid>]
和 --gpg-sign[=<keyid>]
GPG簽名。
-m <msg>
設(shè)置用于創(chuàng)建合并節(jié)點(diǎn)時(shí)的提交信息。
如果指定了--log
參數(shù),那么commit節(jié)點(diǎn)的短日志將會(huì)附加在提交信息里。
--[no-]rerere-autoupdate
rerere即reuse recorded resolution,重復(fù)使用已經(jīng)記錄的解決方案。它允許你讓 Git 記住解決一個(gè)塊沖突的方法,這樣在下一次看到相同沖突時(shí),Git 可以為你自動(dòng)地解決它。
--abort
拋棄當(dāng)前合并沖突的處理過程并嘗試重建合并前的狀態(tài)。
在合并外部分支時(shí),你應(yīng)當(dāng)保持自己分支的整潔,否則的話當(dāng)存在合并沖突時(shí)將會(huì)帶來很多麻煩。
為了避免在合并提交時(shí)記錄不相關(guān)的文件,如果有任何在index所指向的HEAD節(jié)點(diǎn)中登記的未提交文件,git-pull和git-merge命令將會(huì)停止。
通常情況下分支合并都會(huì)產(chǎn)生一個(gè)合并節(jié)點(diǎn),但是在某些特殊情況下例外。例如調(diào)用git pull命令更新遠(yuǎn)端代碼時(shí),如果本地的分支沒有任何的提交,那么沒有必要產(chǎn)生一個(gè)合并節(jié)點(diǎn)。這種情況下將不會(huì)產(chǎn)生一個(gè)合并節(jié)點(diǎn),HEAD直接指向更新后的頂端代碼,這種合并的策略就是fast-forward合并。
除了上文所提到的fast-forward合并模式以外,被合并的分支將會(huì)通過一個(gè)合并節(jié)點(diǎn)和當(dāng)前分支綁在一起,該合并節(jié)點(diǎn)同時(shí)擁有合并前的當(dāng)前分支頂部節(jié)點(diǎn)和對(duì)方分支頂部節(jié)點(diǎn),共同作為父節(jié)點(diǎn)。
一個(gè)合并了的版本將會(huì)使所有相關(guān)分支的變化一致,包括提交節(jié)點(diǎn),HEAD節(jié)點(diǎn)和index指針以及節(jié)點(diǎn)樹都會(huì)被更新。只要這些節(jié)點(diǎn)中的文件沒有重疊的地方,那么這些文件的變化都會(huì)在節(jié)點(diǎn)樹中改動(dòng)并更新保存。
如果無法明顯地合并這些變化,將會(huì)發(fā)生以下的情況:
HEAD指針?biāo)赶虻墓?jié)點(diǎn)保持不變
MERGE_HEAD
指針被置于其他分支的頂部
已經(jīng)合并干凈的路徑在index文件和節(jié)點(diǎn)樹中同時(shí)更新
對(duì)于沖突路徑,index文件記錄了三個(gè)版本:版本1記錄了二者共同的祖先節(jié)點(diǎn),版本2記錄了當(dāng)前分支的頂部,即HEAD,版本3記錄了MERGE_HEAD
。節(jié)點(diǎn)樹中的文件包含了合并程序運(yùn)行后的結(jié)果。例如三路合并算法會(huì)產(chǎn)生沖突。
其他方面沒有任何變化。特別地,你之前進(jìn)行的本地修改將繼續(xù)保持原樣。
如果你嘗試了一個(gè)導(dǎo)致非常復(fù)雜沖突的合并,并想重新開始,那么可以使用git merge --abort
關(guān)于三路合并算法:
三路合并算法是用于解決沖突的一種方式,當(dāng)產(chǎn)生沖突時(shí),三路合并算法會(huì)獲取三個(gè)節(jié)點(diǎn):本地沖突的B節(jié)點(diǎn),對(duì)方分支的C節(jié)點(diǎn),B,C節(jié)點(diǎn)的共同最近祖先節(jié)點(diǎn)A。三路合并算法會(huì)根據(jù)這三個(gè)節(jié)點(diǎn)進(jìn)行合并。具體過程是,B,C節(jié)點(diǎn)和A節(jié)點(diǎn)進(jìn)行比較,如果B,C節(jié)點(diǎn)的某個(gè)文件和A節(jié)點(diǎn)中的相同,那么不產(chǎn)生沖突;如果B或C只有一個(gè)和A節(jié)點(diǎn)相比發(fā)生變化,那么該文件將會(huì)采用該變化了的版本;如果B和C和A相比都發(fā)生了變化,且變化不相同,那么則需要手動(dòng)去合并;如果B,C都發(fā)生了變化,且變化相同,那么并不產(chǎn)生沖突,會(huì)自動(dòng)采用該變化的版本。最終合并后會(huì)產(chǎn)生D節(jié)點(diǎn),D節(jié)點(diǎn)有兩個(gè)父節(jié)點(diǎn),分別為B和C。
當(dāng)合并一個(gè)tag時(shí),Git總是創(chuàng)建一個(gè)合并的提交,即使這時(shí)能夠使用fast-forward模式。該提交信息的模板預(yù)設(shè)為該tag的信息。額外地,如果該tag被簽名,那么簽名的檢測(cè)信息將會(huì)附加在提交信息模板中。
當(dāng)產(chǎn)生合并沖突時(shí),該部分會(huì)以<<<<<<<
, =======
和 >>>>>>>
表示。在=======
之前的部分是當(dāng)前分支這邊的情況,在=======
之后的部分是對(duì)方分支的情況。
在看到?jīng)_突以后,你可以選擇以下兩種方式:
決定不合并。這時(shí),唯一要做的就是重置index到HEAD節(jié)點(diǎn)。git merge --abort
用于這種情況。
解決沖突。Git會(huì)標(biāo)記沖突的地方,解決完沖突的地方后使用git add
加入到index中,然后使用git commit
產(chǎn)生合并節(jié)點(diǎn)。
你可以用以下工具來解決沖突:
使用合并工具。git mergetool
將會(huì)調(diào)用一個(gè)可視化的合并工具來處理沖突合并。
查看差異。git diff
將會(huì)顯示三路差異(三路合并中所采用的三路比較算法)。
查看每個(gè)分支的差異。git log --merge -p <path>
將會(huì)顯示HEAD
版本和MERGE_HEAD
版本的差異。
查看合并前的版本。git show :1:文件名
顯示共同祖先的版本,git show :2:文件名
顯示當(dāng)前分支的HEAD版本,git show :3:文件名
顯示對(duì)方分支的MERGE_HEAD
版本。
Git可以通過添加-s參數(shù)來指定合并的策略。一些合并策略甚至含有自己的參數(shù)選項(xiàng),通過-X<option>
設(shè)置這些合并策略的參數(shù)選項(xiàng)。(不要忘記,合并可以在git merge和git pull命令中發(fā)生,因此該合并策略同樣適用于git pull)。
僅僅使用三路合并算法合并兩個(gè)分支的頂部節(jié)點(diǎn)(例如當(dāng)前分支和你拉取下來的另一個(gè)分支)。這種合并策略遵循三路合并算法,由兩個(gè)分支的HEAD節(jié)點(diǎn)以及共同子節(jié)點(diǎn)進(jìn)行三路合并。
當(dāng)然,真正會(huì)困擾我們的其實(shí)是交叉合并(criss-cross merge)這種情況。所謂的交叉合并,是指共同祖先節(jié)點(diǎn)有多個(gè)的情況,例如在兩個(gè)分支合并時(shí),很有可能出現(xiàn)共同祖先節(jié)點(diǎn)有兩個(gè)的情況發(fā)生,這時(shí)候無法按照三路合并算法進(jìn)行合并(因?yàn)楣餐嫦裙?jié)點(diǎn)不唯一)。resolve策略在解決交叉合并問題時(shí)是這樣處理的,這里參考《Version Control with Git》:
In criss-cross merge situations, where there is more than one possible merge basis, the resolve strategy works like this: pick one of the possible merge bases, and hope for the best. This is actually not as bad as it sounds. It often turns out that the users have been working on different parts of the code. In that case, Git detects that it's remerging some changes that are already in place and skips the duplicate changes, avoiding the conflict. Or, if these are slight changes that do cause conflict, at least the conflict should be easy for the developer to handle
這里簡單翻譯一下:在交叉合并的情況時(shí)有一個(gè)以上的合并基準(zhǔn)點(diǎn)(共同祖先節(jié)點(diǎn)),resolve策略是這樣工作的:選擇其中一個(gè)可能的合并基準(zhǔn)點(diǎn)并期望這是合并最好的結(jié)果。實(shí)際上這并沒有聽起來的那么糟糕。通常情況下用戶修改不同部分的代碼,在這種情況下,很多的合并沖突其實(shí)是多余和重復(fù)的。而使用resolve進(jìn)行合并時(shí),產(chǎn)生的沖突也較易于處理,真正會(huì)遺失代碼的情況很少。
僅僅使用三路合并算法合并兩個(gè)分支。和resolve不同的是,在交叉合并的情況時(shí),這種合并方式是遞歸調(diào)用的,從共同祖先節(jié)點(diǎn)之后兩個(gè)分支的不同節(jié)點(diǎn)開始遞歸調(diào)用三路合并算法進(jìn)行合并,如果產(chǎn)生沖突,那么該文件不再繼續(xù)合并,直接拋出沖突;其他未產(chǎn)生沖突的文件將一直執(zhí)行到頂部節(jié)點(diǎn)。額外地,這種方式也能夠檢測(cè)并處理涉及修改文件名的操作。這是git合并和拉取代碼的默認(rèn)合并操作。
recursive合并策略有以下參數(shù):
該參數(shù)將強(qiáng)迫沖突發(fā)生時(shí),自動(dòng)使用當(dāng)前分支的版本。這種合并方式不會(huì)產(chǎn)生任何困擾情況,甚至git都不會(huì)去檢查其他分支版本所包含的沖突內(nèi)容這種方式會(huì)拋棄對(duì)方分支任何沖突內(nèi)容。
正好和ours相反。
theirs和ours參數(shù)都適用于合并二進(jìn)制文件沖突的情況。
在這種參數(shù)下,git merge-recursive
花費(fèi)一些額外的時(shí)間來避免錯(cuò)過合并一些不重要的行(如函數(shù)的括號(hào))。如果當(dāng)前分支和對(duì)方分支的版本分支分離非常大時(shí),建議采用這種合并方式。
diff-algorithm=[patience|minimal|histogram|myers]
告知git merge-recursive
使用不同的比較算法。
ignore-space-change
, ignore-all-space
, ignore-space-at-eol
根據(jù)指定的參數(shù)來對(duì)待空格沖突。
如果對(duì)方的版本僅僅添加了空格的變化,那么沖突合并時(shí)采用我們自己的版本
如果我們的版本含有空格,但是對(duì)方的版本包含大量的變化,那么沖突合并時(shí)采用對(duì)方的版本
采用正常的處理過程
no-renames
關(guān)閉重命名檢測(cè)。
subtree[=<path>]
該選項(xiàng)是subtree合并策略的高級(jí)形式,將會(huì)猜測(cè)兩顆節(jié)點(diǎn)樹在合并的過程中如何移動(dòng)。不同的是,指定的路徑將在合并開始時(shí)除去,以使得其他路徑能夠在尋找子樹的時(shí)候進(jìn)行匹配。(關(guān)于subtree合并策略詳見下文)
這種合并方式用于兩個(gè)以上的分支,但是在遇到?jīng)_突需要手動(dòng)合并時(shí)會(huì)拒絕合并。這種合并方式更適合于將多個(gè)分支捆綁在一起的情況,也是多分支合并的默認(rèn)合并策略。
這種方式可以合并任意數(shù)量的分支,但是節(jié)點(diǎn)樹的合并結(jié)果總是當(dāng)前分支所沖突的部分。這種方式能夠在替代舊版本時(shí)具有很高的效率。請(qǐng)注意,這種方式和recursive策略下的ours參數(shù)是不同的。
subtree是修改版的recursive策略。當(dāng)合并樹A和樹B時(shí),如果B是A的子樹,B首先調(diào)整至匹配A的樹結(jié)構(gòu),而不是讀取相同的節(jié)點(diǎn)。
以上就是關(guān)于“git中merge的知識(shí)點(diǎn)有哪些”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。