原創文章,轉載請保留出處html
最近剛剛忙完Spark 2.2.0的性能測試及Bug修復,社區又要發佈2.1.2了,國慶期間恰好有空,過了一遍2.1.2的相關JIRA,發現有很多重要修復2.2.0也能用上,接下來須要將有用的PR合到咱們內部維護的2.2.0分支上了。git
常常有朋友問我是怎麼把社區的PR合到本身分支上的,我以前跟他們介紹的作法是基於PR拉分支,在IDEA中單個文件diff合併。若是是偶爾合下社區代碼,這種方式也不算太費事。可是若是PR中改動的文件較多,或者要合併多個PR過來,這種方式也挺麻煩。github
廢話到此,這篇文章是介紹,如何高效地合併Spark社區PR到本身維護的分支(常說的打Patch),固然,針對其餘開源項目,該方法一樣適用。apache
PR:Pull Request是GitHub上的一個功能,開源代碼的貢獻者,經過發起一個Pull Request向社區貢獻代碼。app
通常來講,本身維護一套Spark代碼,須要Fork下社區項目,在clone本身Fork的代碼,進行開發。我這裏以Spark 2.2.0爲例。post
clone本身Fork的倉庫到本地性能
# stanzhai是個人GitHub帳號,你們須要換成本身的倉庫地址 git clone https://github.com/stanzhai/spark.git cd spark
添加一個名爲upstream的遠程倉庫指向社區的版本庫測試
git remote add upstream https://github.com/apache/spark.git
設置PR引用,編輯git配置vi .git/config
,找到upstream,添加最後一行fetchfetch
[remote "upstream"] url = https://github.com/apache/spark.git fetch = +refs/heads/*:refs/remotes/upstream/* fetch = +refs/pull/*/head:refs/remotes/upstream/pr/* # 注意添加這行
同步遠端庫,更新分支引用(每次合併前都須要執行)大數據
git remote update
checkout一個2.2.0的維護分支
git checkout -b my-2.2.0 v2.2.0
咱們建立了一個基於2.2.0的my-2.2.0分支,下面的示例是將社區PR合併到my-2.2.0分支中。
提交給社區的PR大體分爲2類:
被合併到社區的PR已經作了rebase處理,對於這種PR,合併到本身的分支中是很是簡單的事情,直接使用git的cherry-pick就能夠搞定。
咱們以這個卡片爲例:https://issues.apache.org/jira/browse/SPARK-22083
這個卡片被標記爲resolved,並且PR也被合到社區倉庫了:https://github.com/apache/spark/pull/19311,咱們打開這個連接,到頁面下方,找到這個位置:
打開後,會跳轉到這個地址:https://github.com/apache/spark/commit/2c5b9b1173c23f6ca8890817a9a35dc7557b0776,地址中後面的一長串就是咱們須要的commit-id,獲得這個就能夠直接合並代碼了:
git remote update git cherry-pick 2c5b9b1173c23f6ca8890817a9a35dc7557b0776
執行完,提示如下信息就表示合併成功了:
➜ spark git:(my-2.2.0) ✗ git cherry-pick 2c5b9b1173c23f6ca8890817a9a35dc7557b0776 [my-2.2.0 529f5ea55ff] [SPARK-22083][CORE] Release locks in MemoryStore.evictBlocksToFreeSpace Author: Imran Rashid <irashid@cloudera.com> Date: Mon Sep 25 12:02:30 2017 -0700 2 files changed, 153 insertions(+), 13 deletions(-)
若是合併的代碼剛好也被你改過了,那麼有可能會出現衝突,這種狀況正常解決衝突,而後git commit
就能夠了。
因爲一個PR可能包含屢次提交,整合未合併到社區的PR就比較麻煩了。Spark的主幹代碼天天都有變更,直接對比兩個不一樣的分支變更一般會比較大,咱們須要將PR中n次提交的代碼的全部變動梳理出來,而後在作整合。
咱們以這個PR爲例:https://github.com/apache/spark/pull/19301,這個PR實現上還有待改進,但能夠正常工做,所以還沒合入社區,咱們將這個PR合併到my-2.2.0分支,須要進行如下操做:
# 更新遠程倉庫及版本引用信息 git remote update # 基於某個PR建立一個分支,這裏的19301是這個PR在GitHub上的id git checkout -b pr-19301 upstream/pr/19301 git checkout pr-19301 # PR分支大都基於master開發,以upstream/master分支爲基準,從新apply PR分支上的修改 git rebase upstream/master # 經過diff提取此次PR的patch文件 git diff upstream/master > pr-19301.patch # 到目標分支打patch git checkout my-2.2.0 git apply --reject pr-19301.patch # 查看上一步apply的狀態 git status # apply有可能會不成功,還沒有apply的patch被存放到*.rej文件中,須要手動處理,最後提交便可 git commit -a # 清理 rm pr-19301.patch rm *.rej git branch -D pr-19301
上述方法不能保證合PR 100%成功,原則上你的分支和社區代碼約近,衝突越少,越容易處理。Spark 2.x的代碼有很大的變更,把針對2.x的PR打到1.6的分支上,每每是個麻煩事。
文章首發自知乎專欄:Spark大數據技術,專一大數據、Spark相關技術,歡迎關注。
聽說看完這篇文章給個讚的同窗,打Patch都不會遇到衝突 ~(≧▽≦)/~