日本高清免费一本视频100禁_在线不卡欧美精品一区二区三区_国产一区二区好的精华液_中文综合在线_国产啊啊啊视频在线观看_大地资源网免费观看高清

中國專業(yè)IT外包服務(wù)

用心服務(wù)每一天
IT之道-艾銻知道

您當前位置: 主頁 > 資訊動態(tài) > 艾銻分享 >

這才是真正的 Git——分支合并-IT服務(wù)


2020-05-29 20:41 作者:admin

這才是真正的 Git——分支合并-IT服務(wù)

 
電腦運維 服務(wù)器維護,網(wǎng)絡(luò)運維,桌面運維,機房運維,無線改造等服務(wù).電腦運維 高級工程師提供多種解決方案,滿足您所有的IT服務(wù)需求
 
“合并前文件還在的,合并后就不見了”、“我遇到 Git 合并的 bug 了” 是兩句經(jīng)常聽到的話,但真的是 Git 的 bug 么?或許只是你的預(yù)期不對。本文通過講解三向合并和 Git 的合并策略,step by step 介紹 Git 是怎么做一個合并的,讓大家對 Git 的合并結(jié)果有一個準確的預(yù)期,并且避免發(fā)生合并事故。
小程序開發(fā)故事時間
在開始正文之前,先來聽一下這個故事。
如下圖,小明從節(jié)點 A 拉了一條 dev 分支出來,在節(jié)點 B 中新增了一個文件 http.js,并且合并到 master 分支,合并節(jié)點為 E。這個時候發(fā)現(xiàn)會引起線上 bug,趕緊撤回這個合并,新增一個 revert 節(jié)點 E'。過了幾天小明繼續(xù)在 dev 分支上面開發(fā)新增了一個文件 main.js,并在這個文件中 import 了 http.js 里面的邏輯,在 dev 分支上面一切運行正常。可當他將此時的 dev 分支合并到 master 時候卻發(fā)現(xiàn),http.js 文件不見了,導(dǎo)致 main.js 里面的邏輯運行報錯了。但這次合并并沒有任何沖突。他又得重新做了一下 revert,并且迷茫的懷疑是 Git 的 bug。
 
兩句經(jīng)常聽到的話:
—— ”合并前文件還在的,合并后就不見了“
—— ”我遇到 Git 的 bug 了“
相信很多同學(xué)或多或少在不熟悉 Git 合并策略的時候都會發(fā)生過類似上面的事情,明明在合并前文件還在的,為什么合并后文件就不在了么?一度還懷疑是 Git 的 bug。這篇文章的目的就是想跟大家講清楚 Git 是怎么去合并分支的,以及一些底層的基礎(chǔ)概念,從而避免發(fā)生如故事中的問題,并對 Git 的合并結(jié)果有一個準確的預(yù)期。
小程序開發(fā)如何合并兩個文件
在看怎么合并兩個分支之前,我們先來看一下怎么合并兩個文件,因為兩個文件的合并是兩個分支合并的基礎(chǔ)。
大家應(yīng)該都聽說過“三向合并”這個詞,不知道大家有沒有思考過為什么兩個文件的合并需要三向合并,只有二向是否可以自動完成合并。如下圖
 
很明顯答案是不能,如上圖的例子,Git 沒法確定這一行代碼是我修改的,還是對方修改的,或者之前就沒有這行代碼,是我們倆同時新增的。此時 Git 沒辦法幫我們做自動合并。
所以我們需要三向合并,所謂三向合并,就是找到兩個文件的一個合并 base,如下圖,這樣子 Git 就可以很清楚的知道說,對方修改了這一行代碼,而我們沒有修改,自動幫我們合并這兩個文件為 Print("hello")。
 
接下來我們了解一下什么是沖突?沖突簡單的來說就是三向合并中的三方都互不相同,即參考合并 base,我們的分支和別人的分支都對同個地方做了修改。
 
小程序開發(fā)Git 的合并策略
 
了解完怎么合并兩個文件之后,我們來看一個使用 git merge 來做分支合并。如上圖,將 master 分支合并到 feature 分支上,會新增一個 commit 節(jié)點來記錄這次合并。
Git 會有很多合并策略,其中常見的是 Fast-forward、Recursive 、Ours、Theirs、Octopus。下面分別介紹不同合并策略的原理以及應(yīng)用場景。默認 Git 會幫你自動挑選合適的合并策略,如果你需要強制指定,使用git merge -s <策略名字>
了解 Git 合并策略的原理可以讓你對 Git 的合并結(jié)果有一個準確的預(yù)期。
小程序開發(fā)Fast-forward
 
Fast-forward 是最簡單的一種合并策略,如上圖中將 some feature 分支合并進 master 分支,Git 只需要將 master 分支的指向移動到最后一個 commit 節(jié)點上。
 
Fast-forward 是 Git 在合并兩個沒有分叉的分支時的默認行為,如果不想要這種表現(xiàn),想明確記錄下每次的合并,可以使用git merge --no-ff。
小程序開發(fā)Recursive
Recursive 是 Git 分支合并策略中最重要也是最常用的策略,是 Git 在合并兩個有分叉的分支時的默認行為。其算法可以簡單描述為:遞歸尋找路徑最短的唯一共同祖先節(jié)點,然后以其為 base 節(jié)點進行遞歸三向合并。說起來有點繞,下面通過例子來解釋。
如下圖這種簡單的情況,圓圈里面的英文字母為當前 commit 的文件內(nèi)容,當我們要合并中間兩個節(jié)點的時候,找到他們的共同祖先節(jié)點(左邊第一個),接著進行三向合并得到結(jié)果為 B。(因為合并的 base 是“A”,下圖靠下的分支沒有修改內(nèi)容仍為“A”,下圖靠上的分支修改成了“B”,所以合并結(jié)果為“B”)。
 
但現(xiàn)實情況總是復(fù)雜得多,會出現(xiàn)歷史記錄鏈互相交叉等情況,如下圖:
 
當 Git 在尋找路徑最短的共同祖先節(jié)點的時候,可以找到兩個節(jié)點的,如果 Git 選用下圖這一個節(jié)點,那么 Git 將無法自動的合并。因為根據(jù)三向合并,這里是是有沖突的,需要手動解決。(base 為“A“,合并的兩個分支內(nèi)容為”C“和”B“)
 
而如果 Git 選用的是下圖這個節(jié)點作為合并的 base 時,根據(jù)三向合并,Git 就可以直接自動合并得出結(jié)果“C”。(base 為“B“,合并的兩個分支內(nèi)容為”C“和”B“)
 
作為人類,在這個例子里面我們很自然的就可以看出來合并的結(jié)果應(yīng)該是“C”(如下圖,節(jié)點 4、5 都已經(jīng)是“B”了,節(jié)點 6 修改成“C”,所以合并的預(yù)期為“C”)
 
那怎么保證 Git 能夠找到正確的合并 base 節(jié)點,盡可能的減少沖突呢?答案就是,Git 在尋找路徑最短的共同祖先節(jié)點時,如果滿足條件的祖先節(jié)點不唯一,那么 Git 會繼續(xù)遞歸往下尋找直至唯一。還是以剛剛這個例子圖解。
如下圖所示,我們想要合并節(jié)點 5 和節(jié)點 6,Git 找到路徑最短的祖先節(jié)點 2 和 3。
 
因為共同祖先節(jié)點不唯一,所以 Git 遞歸以節(jié)點 2 和節(jié)點 3 為我們要合并的節(jié)點,尋找他們的路徑最短的共同祖先,找到唯一的節(jié)點 1。
 
接著 Git 以節(jié)點 1 為 base,對節(jié)點 2 和節(jié)點 3 做三向合并,得到一個臨時節(jié)點,根據(jù)三向合并的結(jié)果,這個節(jié)點的內(nèi)容為“B”。
 
再以這個臨時節(jié)點為 base,對節(jié)點 5 和節(jié)點 6 做三向合并,得到合并節(jié)點 7,根據(jù)三向合并的結(jié)果,節(jié)點 7 的內(nèi)容為“C”
 
至此 Git 完成遞歸合并,自動合并節(jié)點 5 和節(jié)點 6,結(jié)果為“C”,沒有沖突。
 
Recursive 策略已經(jīng)被大量的場景證明它是一個盡量減少沖突的合并策略,我們可以看到有趣的一點是,對于兩個合并分支的中間節(jié)點(如上圖節(jié)點 4,5),只參與了 base 的計算,而最終真正被三向合并拿來做合并的節(jié)點,只包括末端以及 base 節(jié)點。
需要注意 Git 只是使用這些策略盡量的去幫你減少沖突,如果沖突不可避免,那 Git 就會提示沖突,需要手工解決。(也就是真正意義上的沖突)。
Ours & Theirs
Ours 和 Theirs 這兩種合并策略也是比較簡單的,簡單來說就是保留雙方的歷史記錄,但完全忽略掉這一方的文件變更。如下圖在 master 分支里面執(zhí)行g(shù)it merge -s ours dev,會產(chǎn)生藍色的這一個合并節(jié)點,其內(nèi)容跟其上一個節(jié)點(master 分支方向上的)完全一樣,即 master 分支合并前后項目文件沒有任何變動。
 
而如果使用 theirs 則完全相反,完全拋棄掉當前分支的文件內(nèi)容,直接采用對方分支的文件內(nèi)容。
這兩種策略的一個使用場景是比如現(xiàn)在要實現(xiàn)同一功能,你同時嘗試了兩個方案,分別在分支是 dev1 和 dev2 上,最后經(jīng)過測試你選用了 dev2 這個方案。但你不想丟棄 dev1 的這樣一個嘗試,希望把它合入主干方便后期查看,這個時候你就可以在 dev2 分支中執(zhí)行g(shù)it merge -s ours dev1。
Octopus
這種合并策略比較神奇,一般來說我們的合并節(jié)點都只有兩個 parent(即合并兩條分支),而這種合并策略可以做兩個以上分支的合并,這也是 git merge 兩個以上分支時的默認行為。比如在 dev1 分支上執(zhí)行g(shù)it merge dev2 dev3。
 
他的一個使用場景是在測試環(huán)境或預(yù)發(fā)布環(huán)境,你需要將多個開發(fā)分支修改的內(nèi)容合并在一起,如果不用這個策略,你每次只能合并一個分支,這樣就會導(dǎo)致大量的合并節(jié)點產(chǎn)生。而使用 Octopus 這種合并策略就可以用一個合并節(jié)點將他們?nèi)亢喜⑦M來。
Git rebasegit
rebase 也是一種經(jīng)常被用來做合并的方法,其與 git merge 的最大區(qū)別是,他會更改變更歷史對應(yīng)的 commit 節(jié)點。
如下圖,當在 feature 分支中執(zhí)行 rebase master 時,Git 會以 master 分支對應(yīng)的 commit 節(jié)點為起點,新增兩個全新的 commit 代替 feature 分支中的 commit 節(jié)點。其原因是新的 commit 指向的 parent 變了,所以對應(yīng)的 SHA1 值也會改變,所以沒辦法復(fù)用原 feature 分支中的 commit。(這句話的理解需要這篇文章的基礎(chǔ)知識)
 
對于合并時候要使用 git merge 還是 git rebase 的爭論,我個人的看法是沒有銀彈,根據(jù)團隊和項目習(xí)慣選擇就可以。git rebase 可以給我們帶來清晰的歷史記錄,git merge 可以保留真實的提交時間等信息,并且不容易出問題,處理沖突也比較方便。唯一有一點需要注意的是,不要對已經(jīng)處于遠端的多人共用分支做 rebase 操作。
我個人的一個習(xí)慣是:對于本地的分支或者確定只有一個人使用的遠端分支用 rebase,其余情況用 merge。
rebase 還有一個非常好用的東西叫 interactive 模式,使用方法是git rebase -i。可以實現(xiàn)壓縮幾個 commit,修改 commit 信息,拋棄某個 commit 等功能。比如說我要壓縮下圖 260a12a5、956e1d18,將他們與 9dae0027 合并為一個 commit,我只需將 260a12a5、956e1d18 前面的 pick 改成“s”,然后保存就可以了。
 
限于篇幅,git rebase -i 還有很多實用的功能暫不展開,感興趣的同學(xué)可以自己研究一下。
總結(jié)
 
現(xiàn)在我們再來看一下文章開頭的例子,我們就可以理解為什么最后一次 merge 會導(dǎo)致 http.js 文件不見了。根據(jù) Git 的合并策略,在合并兩個有分叉的分支(上圖中的 D、E‘)時,Git 默認會選擇 Recursive 策略。找到 D 和 E’的最短路徑共同祖先節(jié)點 B,以 B 為 base,對 D,E‘做三向合并。B 中有 http.js,D 中有 http.js 和 main.js,E’中什么都沒有。根據(jù)三向合并,B、D 中都有 http.js 且沒有變更,E‘刪除了 http.js,所以合并結(jié)果就是沒有 http.js,沒有沖突,所以 http.js 文件不見了。
這個例子理解原理之后解決方法有很多,這里簡單帶過兩個方法:1. revert 節(jié)點 E'之后,此時的 dev 分支要拋棄刪除掉,重新從 E'節(jié)點拉出分支繼續(xù)工作,而不是在原 dev 分支上繼續(xù)開發(fā)節(jié)點 D;2. 在節(jié)點 D 合并回 E’節(jié)點時,先 revert 一下 E‘節(jié)點生成 E’‘(即 revert 的 revert),再將節(jié)點 D 合并進來。
Git 有很多種分支合并策略,本文介紹了 Fast-forward、Recursive、Ours/Theirs、Octopus 合并策略以及三向合并。掌握這些合并策略以及他們的使用場景可以讓你避免發(fā)生一些合并問題,并對合并結(jié)果有一個準確的預(yù)期。



相關(guān)文章

IT外包服務(wù)
二維碼 關(guān)閉
主站蜘蛛池模板: 一本一道AV无码中文字幕﹣百度_精品国产色_人妻制服出轨中字在线_91狼人社_日韩女优精品_亚洲一级影片在线观看_欧美精品在线看_天天操夜夜爱 | 成午夜精品一区二区三区_四虎精品国产永久在线观看_日韩女人一级_久久综合给合久久狠狠狠色97_日韩欧美精品一中文字幕_97碰碰碰人妻无码视频_国产熟妇搡BBBB搡BBBB_91久久99久久91熟女精品 | 亚洲jizzjizz妇女_性色AV无码中文AV有码VR_色夜av_久久久www免费人成黑人精品_亚洲线精品一区二区三区四区_四虎影视久久久免费观看_99久久精品免费看国产一区二区三区_日本国产一区二区三区 | 中文字幕欧美成人免费_日韩美女乱淫作爱欣赏_国产伦久视频免费观看视频_西西人体大胆午夜啪啪_八戒八戒神马影院在线4_欧美一级网_亚洲欧美一区二区三区在线_欧美一级免费黄色片 | 青青草国产在线视频_日韩一区二区精品在线观看_精品视频国产_以色列最猛性xxxxx视频_久天啪天天久久99久久_久久精品国产色蜜蜜麻豆_gogo午夜影院_日本成aⅴ人片日本伦 | 亚洲精品久久久久无码AV片软件_日本国产欧美大码a视频_欧美一区二区三区视频在线_久久国产精品偷_日本午夜精品视频_日日干夜夜撸_www.久色_欧美视频完全免费看 | 欧美激情在线一区_成人国产精品视频_中文字幕日韩人妻在线视频_不卡视频国产_91久久在线观看_china直男gay国产_日本黄色影院在线观看_96自拍视频 | 日韩精品一区在线视频_欧美性xxxx极品高清_男人av无码天堂_日韩国产欧美一区二区三区_曰韩一二三区_日本大片一级_日本黄色免费网址_久久综合导航 | 男男被各种姿势C到高潮视频_国内精品久久久久影院古代_1234成人站_一夲道久久东京热_欧美人与拘牲交大全视频_国产aⅴ一区二区三区_中文字幕婷婷日韩欧美亚洲_天天天天操 | 一本一道AV无码中文字幕﹣百度_精品国产色_人妻制服出轨中字在线_91狼人社_日韩女优精品_亚洲一级影片在线观看_欧美精品在线看_天天操夜夜爱 | 日韩欧国产精品一区综合无码_亚洲视频日本有码中文_日韩有码一区_免费在线观看黄视频_一区二区三区色_性xxxxfreexxxxx欧美牲交v_美女露出奶头扒开尿口免费网站_91精品大片 | 激情伊人五月天久久综合_放荡少妇张开双腿任人玩_国产一区二区久久久_99国产在线精品_国产在线视频一区二区_成人一区二_成人一级视频在线观看_a成人毛片 | 日本50岁熟妇XXXX_成人爽视频_神马久草_欧美日韩黄色一级片_亚洲精品一线二线三线无人区_黄色成人影院在线观看_亚洲欧美激情精品一区二区_扒开末成年粉嫩的小缝图片 | 日本黄色一级_国产精品三p一区二区_国产成人片《羞羞》上映_欧美日日日日bbbbb视频_日本视频在线观看一区二区_开心亚洲五月丁香五月_免费国产视频在线观看_中文字幕视频在线播放 | 91爱国产_丰满少妇被猛烈进入高清播放软件_国产一区二区三区_久久亚洲国产_91香蕉亚洲精品_亚洲夜夜欢a∨一区二区三区_www.日本国产_亚洲一区二区中文播放av | 美女裸体爆乳免费网站_亚洲欧美精品国产一级在线_欧美日韩二_四虎库影必出精品8848_b站免费直接观看_九九免费_性欢交69国产精品_午夜提供人体 | 欧美性第一页_av资源在线看片_久久综合精品无码AV一区二区三区_艹逼逼逼_91嫩草影院在线观看_女人被躁到高潮嗷嗷叫免费_91秒拍福利视频_九九在线视频免费观看精彩 | 福利免费在线_中文字幕无码日韩专区免费_亚洲成人一区二区三区四区_久久99精品久久久97夜夜嗨_内射高潮享受视频在线观看_中文字幕av无码专区第一页_一区二区三区在线观看免费视频_新疆老熟女厉害 | 免费A级毛片无码鲁大师_又爽又黄axxx片免费观看_热久热久_欧美videosdesexo肥婆_亚洲a在线观看_av毛片免费观看_爆乳熟妇一区二区三区_日美韩一区二区三区 | 青青精品视频_成人h版_x88av乱视频_精品香蕉一区二区三区_欧美视频日韩_人妻少妇精品无码专区二区_国产精品亚韩精品无码A在线_日本老妇xxxxx免费 | 中文字幕日韩精品欧美一区_av国产精品毛片一区二区小说_国产黄色免费看_亚洲精品黑牛一区二区三区_成人亚洲免费_国产高清视频在线观看一区二区_91大神在线观看视频_久久久国产精品人人片99精片欧美一 | 日韩视频在线第一页_欧美黑人欧美黑人双交_在线99_亚洲伊人成人_久久人人爽人人人人片_人妻人人澡人人添人人爽人人玩_久久香蕉99_天天看国91产在线精品福利桃色 | 欧美人与动牲交A免费观看_一本色道综合久久亚洲精品_变态孕交videosgratis孕妇_国模无码视频一区二区三区_无码精品人妻一区二区三刘亦菲_一级片视频播放_一级成人毛片_FUCK东北老女人HD对话 | 亚洲精品tv久久久久久久久_亚洲免费av第一区第二区_在线亚洲网站_性一交一乱一色一视频_国产xxxx在线观看_一区不卡在线_久久久蜜桃精品_色哟哟精品丝袜一区二区 | 男人进去女人爽免费视频_国内激情_午夜影院一级_狠狠做五月深爱婷婷_黄色一级大片免费_午夜久久久久久久久久久久_无码人妻丰满熟妇A片护士_免费看黄色大全 | 美女一级特黄大片_亚洲中文字幕无码AV正片_亚洲性区_国产黄色大片在线免费观看_日本国产欧美_草草影院国产_香港三级韩国三级日本三级国产_亚洲AV成人无码人在线观看堂 | 久久精品人妻中文系列_国产又爽又大又黄A片图片_久久久久久久影视_欧美一区二区三区成人精品_欧美精品一区二区三区久久_亚洲精品91天天久久人人_91视视频在线观看入口直接观看_老妇xxxxx | 欧美久久久久_久久国产精品亚洲人一区二区三区_久久久成人毛片无码_亚洲一区二区在线看_美女张开腿黄网站免费_亚洲大片69999_中国精品少妇hd_精品欧美国产 | 中文字幕无码久久精品青草_狠狠躁天天躁中文字幕无码_公粗挺进了我的密道在线播放贝壳_蜜臀AV无码人妻精品_免费a在线看_国产精品人妻无码久久青草_正在播放国产第九十二_777cc成人 | 四虎影视8848h_日本一卡2卡三卡4卡无卡免费网站_亚洲欧美精品_超清精品丝袜国产自在线拍_精品国产福利在线_xxx国产在线_二区top_麻豆91av | 欧美午夜一区二区三区精美视频_亚洲艳妇_四虎影院观看_久久免费视频观看_成人中文网_狠狠色噜噜狠狠狠狠色综合久AV_ai杨幂被弄高潮在线看_亚洲制服丝袜欧美 | 天堂中文字幕在线_欧美最猛性xxxxx(亚洲精品)_99不卡视频_性欧美丰满熟妇XXXX性_国产乱码卡二卡三卡4_欧美性一级_国产精品一区二区无线_国产美女爆乳呻吟视频 | 欧美在线视频一区_日本精品一区二区三区在线播放_日本熟妇人妻xxxx_又色又爽美女网站_亚洲AV无码成人精品区一区_做暖暖小视频免费xo_军人野外吮她的花蒂无码视频_亚洲中文字幕无码人在线 | 成年美女黄网_91se亚洲综合色区_中文字幕亚州国产制服_久久夜色精品国产网站_鲍鱼av_少妇毛片一区二区_四虎影院永久在线观看_欧美自拍偷拍一区 | 九一亚洲_日韩区欧美区_亚洲AV无码一区东京热不卡_免费观看在线毛片_亚洲一区二三区好的精华液_国产丰满果冻videossex_日本不卡不码高清视频_欧美a免费 | 九九视频精品全部免费播放_国产51人人成人人人人爽色哟哟_全职猎人1999在线动漫免费观看_91好色视频_九色在线网站_超碰97人人草_亚洲成AV人片高潮喷水_黄色成人在线播放 | 台湾佬中文娱乐22vvvv_日日干天天干_性爱免费视频_国产在线精品一区在线观看_一区二区不卡免费视频_国产无一区二区_偷看少妇自慰XXXX_亚洲永久精品www | 国产女高清在线看免费观看_色无码av在线播放_久久爽久久爽久久av东京爽_曰本丰满熟妇XXXX性_在线播放网址_日本轮理片_国产精品高潮呻吟爱久久AV无码_国产youjizz | 色综合天天综合网国产成人网_天天躁夜夜躁狠狠久久成人网_少妇挑战3个黑人惨叫4P国语_久久无码av三级_手机看片日韩欧美_又色又湿又黄又爽又免费视频_亚洲精品国偷自产在线_妺妺窝人体色WWW看人体 | 午夜国产福利_喷水久久_欧美黑人喷潮水xxxx_亚洲久久久久久久_欧美色综合网站_av免费提供_亚洲av永久无码天堂网小说区_日韩午夜视频在线 | 久久久久中精品中文字幕19_奇米影视777四色狠狠_日本高清在线播放_国产人妻aⅴ色偷_av最新地址_国产无人区二卡三卡四卡不见星空_一级黄色带片_18成人片黄网站WWW |