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_黄色录像久久_国产普通话尤物吞精视频_丰满少妇被猛烈进入毛片_毛片在线免费观看网站_我把护士日出水了视频_www.亚洲视频.com | 曰韩三级_欧美热久久_日韩天堂一区_久久99精品国产99久久6_亚洲精品无码av久久久久_国产成人啪精品午夜网站a片免费_欧美激情视频一区二区三区在线播放_国产高清成人在线观看 亚洲国产精品久久人人爱_污导航在线观看_中文字幕高清在线播放_一区二区三区精_免费观看欧美日韩亚洲_可以免费看av_黄网十三区_精品人妻无码区在线视频 | 依人在线视频_亚洲精品久久久久久久_一本久久A精品一区二区_中国一级片在线播放_精品特级毛片_九九视频在线观看视频6_成年日韩免费大片黄在线观看_男人插女人的免费视频 | 日韩精品一级毛片_国产在线观看香蕉视频网_亚洲a在线播放_亚洲一及片_久久亚洲综合色_国产AV国片精品JK制服丝袜_91蜜桃视频在线观看_亚洲vs日韩vs欧美vs久久 | jj男色网_正在播放长泽梓免费观看_7777888色淫网站免费视频_亚洲午夜精品视频_国产日韩在线_午夜A片免费_亚洲字幕AV一区二区三区四区_不卡av中文字幕手机看 | 天天搞美女视频_久久久亚洲欧洲日产国码二区_边摸边吃奶边做爰视频网站_天天干天天爱天天操_欧美熟妇性XXXX欧美熟人多毛_亚洲春色CAMELTOE一区_免费国无人区码卡二卡_亚洲精品国产黑色丝袜 | 国产99视频精品免费视频76_美女内射毛片在线看_亚洲不卡一区二区三区_欧美精品无码一区二区三区_国产在线观看不卡一区二区三区_青草视频免费在线观看_黑人强伦姧人妻久久_99视频免费 | 中文字幕亚洲一区二区三区_人人妻人人玩人人澡人人爽_国产精品乱码精品久久久_国产二级av_日韩免费一区二区三区在线播放_亚洲成人1区2区_亚洲天堂导航_国产视频三 | 国产乱一乱二乱三_免费黄色在线_国产高清一_香蕉国产9_国产精品午睡沙发系列_国产精品午夜无码A体验区_欧美人与动牲交ZOZO_国产精品久久久久久久久大全 | xxx麻豆_亚洲AV无码AV有码AV_国产女做a爱免费视频_va久久久久精码专区_国产精品一区二区三区久久久久_亚洲av永久精品无码_中文字幕AV无码免费一区_久久久精品福利视频 | 日本中文字幕网址_亚洲久久色_精品国产一区二区亚洲人成毛片_人成免费a级毛片_真人在线观看色网视频_日韩AV高潮喷水在线观看_久草影视在线_国产女人爽到高潮久久久4444 | 亚洲精品国产精品乱码不99热_FREE性丰满HD毛多多_永久免费av无码不卡在线观看_国产精品亚洲一区二区三区妖精_日日天干夜夜人人添_国产欧美成人不卡视频_中文字幕88页_人与动人物XXXX毛片 | 精品一二三区视频_天天激情综合_国产高潮呻吟久久_国内精品在线一区_91精品国产色综合久久久蜜臀_综合在线视频_国产成人精品午夜福利_国产av无码专区亚洲av软件 | 青青成线在人线免费啪_精品亚洲国产成人_中文精品久久久久鬼色_欧洲黄色录像_国产精品一区二区免费久久精品_狠狠色丁香婷婷综合久久来来去_精品自拍亚洲一区在线_国内a级毛片免费观看品善网 | 少妇穿牛仔裤一级av毛片_狠狠干狠狠搞_成年网站在线播放_久久久亚洲国产精品_操bb影院_老少交欧美另类_国产视频xxx_国产精品久久人妻无码网站 | 久久精品一区二区三区四区_夜夜操夜夜操夜夜操_国产草比视频_日本国产黄色_偷拍一区二区三区视频_久久成人人人人精品欧_中出乱码av亚洲精品久久天堂_欧美日韩一区二区三区在线看黄 | 2021年天堂无码视频_久久在精品线影院精品国产_免费成人av网址_国产刺激视频在线观看_一本大道久久a久久精品综合1_91杏吧_chinese蓝男色video_小香蕉av | 日日射视频_免费观看黄色片_成人你懂的_日日操夜夜爱_成人一区二区三区视频在线观看_四虎娱乐_公和熄小婷乱中文字幕_国产精品久久久久久久久久免费 | 99国产精品99久久久久久_黄色大片免费网址_国产黄片自拍亚洲AV_成a人v_国产95亚洲_www.免费黄色_欧美成人网视频_韩国色网 日韩免费区_精品国产AV色一区二区深夜久久_av边做边流奶水无码免费_欧洲黄色级黄色99片_国产a网站_免费久久一级欧美_97碰碰碰人妻无码视频_三级黄色性生活视频 | 日本免费一区二区在线观看_亚洲无码专区三区在线观看_国产成人精品久久二区二区_av天堂精品久久久久_伊波拉病毒在线观看超清国语_国产一区二区三区_JIZZ成熟丰满韩国女人少妇_亚洲精品成人片在线观看 | 国产精品无毒不卡_欧美成人A片一区二区不卡_久草在线小说_午夜资源站_欧美大肥婆大肥BBBBB_99精视频_国产偷久久一级精品_兔子先生第三季免费视频播放 | 国产精选在线播放_日韩人妻无码一区二区三区久久_国产精品中文字幕一区_免费观看日韩一级片_xxxx性按摩bbbb_国产69精品99久久久久久宅男_好好热av_羞羞答答二区 | 欧美一区欧美二区_久久伊人精品中文字幕有软件_天天色综合合_久久情侣视频_久久aⅴ人妻少妇嫩草影院_91操bb_伊人久久视频_在线视频观看免费视频18 | 边摸边脱吃奶边高潮视频免费_91精品国产综合久久久久久久久_无码伊人66久久大杳蕉网站谷歌_国产丝袜精品视频_日本韩国国产_久久精品欧洲_www.99色_www.91桃色 | 99精品久久毛片a片_日本边添边摸边做边爱的网站_国产免费97_精品久久久一二三区_99久RE热视频这里只有精品6_亚洲一级大黄大色毛片_久久国产精品麻豆_av毛片在线观看地址 | 日韩av一级片_中文字幕在线视频日本_日本午夜一区_国产亚洲欧美一级_日批视频在线观看网站_在线视屏_亚洲AV无码无一区二区三区_国产成人精品无码一区二区 色婷婷五月综合亚洲影院_免费在线观看亚洲视频_欧美一级日韩一级无毒不卡_国产精品高潮在线_国产一区久久_狠狠操一区二区三区_亚洲国产精品无码久久久久久曰_美女黄色网址 | 国产精品自在_精品一二三四视频_日韩影院一区二区_精品手机在线视频_日日做夜狠狠爱欧美黑人_在线视频1区_国产瑟瑟视频_亚洲91久久 | 中文字幕在线观看不卡视频_色悠久久久久综合网国产_黄色大片视频_真人作爱免费视频_男女性色大片免费网站_精品人妻少妇一区二区三区_四虎影视8848h_日韩人妻无码一区二区三区99 | 色影天堂_国产亚洲毛片在线_黄色av免费观看_日本最新免费二区三区_放荡老师张开双腿任我玩_亚洲成人www_岛国无码av不卡一区二区_一二三四五社区在线高清观看 | 国产欧美在线视频_激情丁香_亚洲丝袜视频_欧美性猛交xxxx乱大交喷浆_久草在线视频在线_久久综合给合综合久久_久草一区二区_直接观看黄网站免费视频 | 精品自拍视频_性videos欧美熟妇hdx_国产精品美女久久久浪潮软件_欧美情侣性视频_午夜播放器在线观看_黄色一级片免费_欧美色精品vr_91久久久精品国产一区二区蜜臀 | 国产色综合视频_亚洲第一成人久久网站_免费看奶_亚洲日本韩国一区_亚洲a区在线视频_奇米影视9999_成人精品视频网站_好大好爽受不了了h | 91社区在线观看高清_91免费版网址_成人福利国产精品视频_日韩一级免费大片_中文字幕第十五页_亚洲精品99999_幻女bbwxxxx_久久久久av综合网成人 | 国产成人亚洲精品另类动态图_欧美一乱一性一交一视频_100日本xxxxxxxxx15_日本老妇人乱xxy_日韩欧美综合在线视频_日韩专区一区_4455四色永久在线_久久艹色 | 女的被到爽羞羞视频_色之久久_中文字幕精品一区_精品久久久一二三区播放播放播放视频_香蕉成人国产精品免费看网站_国产欧美日韩高清_天码AV无码一区二区三区四区_中文字幕免费在线 | 美女乱淫aaa视频_四虎四虎_麻豆少妇_欧美日韩亚洲免费_可以免费看av的网址_天天操综合网_亚洲精品无人一区二区_久久在草 | 九一麻豆精品_男人日女人的网站_欧美天堂在线视频_麻豆伦理视频_国产精品国产亚洲伊人久久_久久久精品蜜桃_亚洲乱仑_久久久免费播放 | 日韩精品中文字幕无码专区_欧美日韩综合精品_91成人看片_蜜臀av免费一区二区三区久久乐_粉色视频在线观看免费观看_亚洲av日韩av综合_日本艳妓BBW高潮一19_女人扒开屁股让男人桶 | 久久丫精品国产免费_黑人狂躁日本妞一区二区三区_男人午夜网站_成人高清在线视频_精品一区在线免费观看_8mav精品成人_夜精品无码A片一区二区蜜桃_aⅴ色国产欧美 | 永久黄软件免费观看_国产三级久久久久_欧美精品无码久久久潘金莲_成人一级大片_午夜免费福利片_亚洲综合一区国产精品_亚洲av日韩精品久久久久_哥也色视频 | 中文字幕不卡免费视频_亚洲欧美日韩另类精品一区_少妇午夜三级伦理影院播放器_亚洲精品乱码久久观看网_久青草无码视频在线观看_在线不卡a资源高清_欧美第2页_亚洲国产成人在线播放 |