前言
利用git版本控制工具時,我們通常會從主分支拉出新分支進行開發,開發完成後建立pr(也就是pull request),讓其他小夥伴幫忙review,確定代碼沒有問題後再將新分支合并到主分支上。但是,你真的理解pull request中比較的兩個分支到底是誰嗎?
下面以一個虛擬案例進行說明:假設主分支名為“Master”,拉出來的新分支名為“developBrance1”。
註:圖中的箭頭指代工作推進方向,而不是提交的指向(提交指向總是由當前提交指向父提交,和這裡的箭頭是反著的)
最簡單的情況
中,我們從主分支Master的m1提交點拉出新分支developBranch1,然後在developBranch1分支上開發(開發過程中產生了d1、d2、d3共3個提交),開發完成後建立pr,然後經過Review後將其合并到主分支上形成新的提交點N。自然而然地,我們建立pr時選擇的源和目標為:
src[developBranch1] -> dest[Master]
我們期望pr比較的是developBranch1和Master這兩個分支的最新提交點,pr實際比較的也是developBranch1的d3提交點和Master分支的m1提交點之間的差異。
增加一點複雜度
假設現在有其他小夥伴和你一同工作(這才是工作中的情境),另外一名小夥伴也從Master分支的m1提交點拉出分支developBranch2進行開發,併產生了若干提交,而且在我們開發完成之前已經合并到了Master分支上:
現在我們建立pr時,源和目標自然還是:
src[developBranch1] -> dest[Master]
但此時pr實際比較的是developBranch1和Master這兩個分支的最新提交點嗎( developBranch1的d3提交點和Master分支的m2提交點)?
答案:不是的。現在pr比較的其實是developBranch1的d3提交點和Master分支的m1提交點,和上面最簡單的情況完全沒有差別!
其實pr的底層這樣實現非常有道理:
我們建立pr時,兩個分支比較的差異只是自己開發的內容。試想,如果合作開發情況下比較developBranch1的d3提交點和Master分支的m2提交點之間的差異,那我們會同時看到其他小夥伴的開發內容,你會想,這不是反應了“最新工作進度”嗎?不就是多看一個小夥伴的代碼嗎?好,再試想如果同時有很多人開發,我們提交自己的代碼時,夾雜了許多其他小夥伴的代碼,你會不會因找不到自己開發的代碼而發瘋?
“最新工作進度”的疑惑還在吧?下面來解答。
git是如何反映最新工作進度的?
其實,git合并不同分支時,會自動取它們的並集,以保持最終工作進度。就拿說,如果developBranch1的d3提交點和developBranch2的o2提交點之間不存在衝突,兩者的開發工作最終都會在m3中體現(當然,有衝突了就需要手動解決)。
現在還有一個問題,pr比較的原理是什嗎?
pr比較的是:
源分支的最近提交點和源分支和目標分支的最近公用父提交節點之間的差異。在文中第二張圖中,可以看到源分支是developBranch1,目標分支是Master,兩個分支的最近公用父提交節點是m1;所以最終比較的就是源分支的最近提交點d3和m1。
探索欲強的讀者也可以試試把不同分支分別作為pr的源和目標,觀察pr輸出的差異,以加深印象。
後記
其他更為複雜的分支pr原理類似,只是需要結合更為複雜的合并策略進行分析。文中若有疏漏,歡迎指正補充。
好了,該去複習複習尋找兩節點最近公用父節點的原理了^_^
比較好的文章推薦
zhuanlan.zhihu.com/p/26227256