456成人影院在线观看_亚洲a毛片_日韩9999_伊人网老司机_一本免费视频_最近高清日本免费

IT之道-艾銻知道

您當前位置: 主頁 > 資訊動態 > 艾銻分享 >

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


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

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

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



相關文章

IT外包服務
二維碼 關閉
主站蜘蛛池模板: 亚洲热妇无码播放aV另类_午夜视频福利在线_免费观看无码不卡av_69堂免费视频_4hu最新网_色婷婷av一区二区三区久久_麻豆视频观看免费视频观看_国产精品欧洲 | 国产精品96久久久久久久_在线免费观看av网站_黄色真人毛片_国产免费永久在线观看_AB无码精品一区二区三区人妖_国产精品人人做人人爽人_日韩成人极品在线内射3p蜜臀_无码专区男人本色 | 九色免费视频_国产精品一区二区亚洲_www.久久综合_亚洲九九影院_日本国产免费_狠狠色噜噜狠狠狠狠色综合久AV_亚洲精品美女久久777777_中文一区二 | 九色精品91_性做久久久久免费观看_日韩精品123区_国产精品久久9_国产精品色拉拉_国产精品wwwcom976con_亚洲高清资源在线观看_九一精品视频一区二区三区 | 国产精品草草在线观看_国产成人亚洲影院在线播放_亚洲一二三四区不卡_黄频视频在线观看_性欧美极品另类_免费在线看一区_人妻无码精品久久亚瑟影视_息与子五十路中文字幕 | 欧美顶级大胆免费视频_国产艳妇AV在线_欧美级特黄AAAAAA片_a级大片在线观看_www国产_60老熟女多次高潮露脸视频_草莓AV福利网站导航_VideOS性饥渴 | 91热爆视频_韩国av一区二区_夜夜躁狠狠躁日日躁视频_av在线免费播放_双飞两少妇国语对白_中文字幕在线乱码不卡二区区_色综合久久中文娱乐网_成年站免费网站看V片在线 | 四虎地址_国产精品午夜久久_久久精品精品_久久久久狠狠高潮亚洲精品_久99精品久久久_国产色悠悠_台湾佬中文娱乐22vvvv_久久国产一 | 搡bbbb搡bbb搡视频一级_任你躁国产老女人_成人深夜www视频免费软件_日日干夜夜操天天操_中文字幕亚洲一区一区_免费一级婬片AAA毛片肥肥女_国产成人欧美一区二区三区八_www.99日本精品片com | 成人国产精品一级毛片视频毛片_爱看久久_丰满少妇夜夜爽爽高潮水网站_国产成人涩涩涩视频在线观看_国产妓女一级在线视频_亚洲国产极品_av片网址_亚洲少妇最新在线视频 | 精品99久久_国产精品在线看_大香伊蕉最新视频_亚洲色大18成人网站WWW在线播放_一区二区免费视频_国产午夜福利片1000无码_久久精品亚洲人成影院_久草在线手机视频 | 91婷婷_97在线视频人妻无码_国产成人AV无码精品_欧美大片久久国产欧美日韩精品_亚洲人a成www在线影院_9l国产精品久久久久麻豆_亚洲国产日韩欧美视频二区_中文字幕有码无码人妻在线 | 欧美日韩中文字幕一区二区高清_人与性动交aaaabbbb_国产一区二区三区四区五区加勒比_国产成人综合欧美精品久久_99久久国产宗和精品1上映_日本丰满人要无码视频_日韩成人区_国产美女视频黄 | 日韩在线免费不卡_亚洲黄色小说视频_中日韩欧美中文字幕_国产免费一级大片_国产成人99_日欧一片内射VA在线影院_japanesemon乱_亚洲中文字幕无码久久 | 日本成本人三级在线观看_最近中文字幕免费mv2019在线_色爱综合网中文字幕第1页_综合网中文字幕_综合激情久久_caoporn超碰最新公开_久久久久久久久久久国产_日本特黄特色大片免费视频老年人 | 亚洲美女视频_日本69xxxxx_在线观看国精产品一区_国产精品久久久久久久久久久久久久_狠狠操社区_伊人精品成人久久综合软件_在线岛国片免费无码AV_秋霞无码一区二区视频在线观看 | 精品欧美日韩国产日漫一区不卡_野花社区WWW视频日本_中文字幕色av一区二区三区不卡_视频自拍一区_亚洲国产综合精品中久_少妇与子乱在线观看_国产成人精彩在线视频_亚洲一区二区无码偷拍 | 爆乳无码系列肉感在线播放_国产成人亚洲精品无码车A_在线观看的毛片_曰韩少妇内射免费播放_国产人妻aⅴ色偷_天天摸天天操天天舔_国产成人福利在线观看_狠狠色丁香六月色 | 天堂资源中文_黄色av免费在线_天堂在线中文字幕_亚洲国产精品婷婷久久久久_无码成人精品日本动漫纯H_亚洲日韩激情无码一区_久久亚洲AV永久无码精品_影音先锋在线中文字幕 | 久久久久久久美女_国产A级护士毛片_国产亚洲精品久久久999密壂_欧美日韩免费在线观看_日韩一级片免费视频_国产精品久久久久久婷婷动漫_国产在线精品免费_久久在现视频 | 一级久久久_国产真人做爰免费视频_久久精品国产亚洲aⅴ瑜伽_国产美女爆乳呻吟视频_国产人成久久久精品_日韩精品无码久久一区二区三_欧美亚洲国产精品久久高清_成人综合久久综合 | 久草亚洲天堂_狠狠操av_精品国内_一级不卡免费视频_91久久精品一区二区三区_91精品午夜窝窝看片_蜜桃色欲AV久久无码精品_国产一区福利在线 | 久久精品一区_91影院在线观看_男男做爰猛烈高潮在线观看_天天综合网网欲色_无码一卡二卡三卡四卡_午夜影院在线观看免费_饥渴少妇高潮视频大全_488成人啪啪片 | 草草亚洲视频_九色综合网_春色伊人网_日韩ac_草草草视频_二区视频在线观看_亚洲国产精品专区久久_国产在线视频不卡一区二区三区 欧美a级成人网站免费_精品国产天堂_国产色婷婷五月精品综合在线_成人三级网址_婷婷久久无码欧美人妻_一级毛片在线观看视频_小12萝8禁在线喷水观看_精品一区二区在线观看视频 | 欧美亚洲另类图片_男人的天堂免费视频_色噜噜狠狠色综合网图区_阿娇艳z门照片无码av4i_韩国一级片免费_一个人看的www视频免费播放_嗯快点别停舒服好爽受不了了_毛片成人免费看A片 | 国产亚洲精品久久久久久打不开_日本熟妇厨房XXXXX乱_99久久精品国产免费_国产综合13P_亚洲综合免费视频_99爱在线精品免费观看_中文字幕成熟丰满人妻_日本高清WWW午色夜在线视频 | 亚洲欧美精选_校花被肉干高h潮不_久久久久国产一区二区三区_v片在线免费观看_青草娱乐在线_天天爱天天做天天爽_久久精品一级片_中国xxxx自慰xxxx | 91超碰免费_撕开奶罩揉吮奶头视频_成年免费无码动漫AV片在线观看_免费精品视频一区二区_老熟妇性老熟妇性色变态_91综合色_美女国产毛片a区内射_蜜桃传媒一区二区 | 超碰在线公开97_成人水多啪啪片_国产精品裸体一区二区三区_久久免费在线_制服在线无码专区_91国偷自产一区二区三区蜜臀_伊人春色欧美_精品首页 | 国产在线观看91精品_色99在线_国产精品区二区三区日本_91九色磁力_亚色中文成人yase999co_xxxxx亚洲_正在播放av_久久久久一区二区三区四区 | 人妻无码久久一区二区三区免费_人妻偷人VA精品国产旡码_久草在线视频网_中文字幕在线观看_国产嫩草影院久久久久_成人动漫网站入口_高清国产一区二区_狠狠躁夜夜躁人人躁婷婷91 | 无码专区永久免费AV网站_日本少妇被黑人xxxxx软件_狂野欧美激情性XXXX按摩_av喷水高潮喷水在线观看com_豆奶导航_中国av一级片_欧美一区二区三区国产精品_国产精品丝袜肉丝出水 | 岛国a视频在线观看免费18在线看_午夜色场_成人激情视频网站_日韩观看_亚洲欧洲综合有码无码_国色天香卡一卡二乱码_老司机福利在线视频_免费国产高清在线精品一区 | 公粗挺进了我的密道在线播放贝壳_国产香蕉青春草原久久_最近最新中文免费字幕一_久久久久久久久久久91_中文字幕在线播放_国产精品一二三四区_chien国产乱露脸对白_日韩视频免费看 | 国产电视伦理怡红院在线观看_9999精品免费视频_国产精品高潮呻吟av久久4虎_黄色成人在线播放_国产帅男男GAY网站视频_久久国产精品无码一区_青青草精品在线_亚洲欧美中日韩 | 国产精品入口a级_免费羞羞视频无遮挡噼啪男男_国产农村熟妇videos_精品国产精品国产_melody高清在线观看_亚欧在线高清专区_欧美人免费视频网站在线_中文字字幕乱码视频高清 | 免费a国产_91高清网站_古典武侠激情亚洲精品一区_99re免费视频精品全部_国产精品萝li_福利视频在线看_久久久亚洲精品无码_日日噜夜夜爽精品一区 | japanese69极品少妇_卡一卡二卡三免费视频_亚洲精品中文字幕无码蜜桃_在线观看美女网站大全免费_中文字幕制服丝袜一区二区三区_久久久精品国产一区_九九九在线观看_想看一级黄色 | 亚洲亚洲精品三区日韩精品在线视频_6699久久久久久久77777'7_免费在线观看视频完整_精品av中文字幕在线毛片_aⅴ免费在线观看_深夜免费观看视频_日韩一区二区观看_日韩国产成人无码AV毛片蜜柚 | 91九色视频在线_97人人爱_成人久草_色wwww全部免费_一级簧片免费看_91麻豆精品国产91久久久更新资源速度超快_国产98在线_欧美老妇与ZOZOZ0交 | 成·人免费午夜视频_久草热这里有精品6_一二三四在线社区观看社区7_人摸人人人澡人人超碰手机版_www..99热_欧美又粗又大BBBBXXXX_日日操夜夜操天天爽_欧美诱惑一区 |