前言
利用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原理類似,只是需要結合更為復雜的合並策略進行分析。文中若有疏漏,歡迎指正補充。
好了,該去復習復習尋找兩節點最近公共父節點的原理了^_^
比較好的文章推薦