學(xué)習(xí)完整課程請(qǐng)移步 互聯(lián)網(wǎng) Java 全棧工程師
Pull Requests 是 Bitbucket 上方便開發(fā)者之間協(xié)作的功能。提供了一個(gè)用戶友好的 Web 界面,在集成提交的變更到正式項(xiàng)目前可以對(duì)變更進(jìn)行討論。

開發(fā)者向團(tuán)隊(duì)成員通知功能開發(fā)已經(jīng)完成,Pull Requests 是最簡單的用法。開發(fā)者完成功能開發(fā)后,通過 Bitbucket 賬號(hào)發(fā)起一個(gè) Pull Request。這樣讓涉及這個(gè)功能的所有人知道,要去做 Code Review 和合并到 master 分支。
但是,Pull Request 遠(yuǎn)不止一個(gè)簡單的通知,而是為討論提交的功能的一個(gè)專門論壇。如果變更有任何問題,團(tuán)隊(duì)成員反饋在 Pull Request 中,甚至 push 新的提交微調(diào)功能。所有的這些活動(dòng)都直接跟蹤在 Pull Request 中。

相比其它的協(xié)作模型,這種分享提交的形式有助于打造一個(gè)更流暢的工作流。SVN 和 Git 都能通過一個(gè)簡單的腳本收到通知郵件;但是,討論變更時(shí),開發(fā)者通常只能去回復(fù)郵件。這樣做會(huì)變得雜亂,尤其還要涉及后面的幾個(gè)提交時(shí)。Pull Requests 把所有相關(guān)功能整合到一個(gè)和 Bitbucket 倉庫界面集成的用戶友好 Web 界面中。
解析 Pull Request
當(dāng)要發(fā)起一個(gè) Pull Request,你所要做的就是請(qǐng)求(Request)另一個(gè)開發(fā)者(比如項(xiàng)目的維護(hù)者),來 pull 你倉庫中一個(gè)分支到他的倉庫中。這意味著你要提供 4 個(gè)信息(源倉庫、源分支、目的倉庫、目的分支),以發(fā)起 Pull Request。

工作方式
Pull Request 可以和功能分支工作流、GitFlow 工作流或 Forking 工作流一起使用。但 Pull Request 要求要么分支不同,要么倉庫不同,所以不能用于集中式工作流。在不同的工作流中使用 Pull Request 會(huì)有一些不同,但基本的過程是這樣的:
- 開發(fā)者在本地倉庫中新建一個(gè)專門的分支開發(fā)功能。
- 開發(fā)者 push 分支修改到公開的 Bitbucket 倉庫中。
- 開發(fā)者通過 Bitbucket 發(fā)起一個(gè) Pull Request。
- 團(tuán)隊(duì)的其它成員 review code,討論并修改。
- 項(xiàng)目維護(hù)者合并功能到官方倉庫中并關(guān)閉 Pull Request。
在功能分支工作流中使用 Pull Request
功能分支工作流用一個(gè)共享的 Bitbucket 倉庫來管理協(xié)作,開發(fā)者在專門的分支上開發(fā)功能。但不是立即合并到 master 分支上,而是在合并到主代碼庫之前開發(fā)者應(yīng)該開一個(gè) Pull Request 發(fā)起功能的討論。

功能分支工作流只有一個(gè)公開的倉庫,所以 Pull Request 的目的倉庫和源倉庫總是同一個(gè)。通常開發(fā)者會(huì)指定他的功能分支作為源分支,master 分支作為目的分支。
收到 Pull Request 后,項(xiàng)目維護(hù)者要決定如何做。如果功能沒問題,就簡單地合并到 master 分支,關(guān)閉 Pull Request。但如果提交的變更有問題,他可以在 Pull Request 中反饋。之后新加的提交也會(huì)評(píng)論之后接著顯示出來
在功能還沒有完全開發(fā)完的時(shí)候,也可能發(fā)起一個(gè) Pull Request。比如開發(fā)者在實(shí)現(xiàn)某個(gè)需求時(shí)碰到了麻煩,他可以發(fā)一個(gè)包含正在進(jìn)行中工作的 Pull Request。其它的開發(fā)者可以在 Pull Request 提供建議,或者甚至直接添加提交來解決問題。
在 GitFlow 工作流中使用 Pull Request
GitFlow 工作流和功能分支工作流類似,但圍繞項(xiàng)目發(fā)布定義一個(gè)嚴(yán)格的分支模型。在 GitFlow 工作流中使用 Pull Request 讓開發(fā)者在發(fā)布分支或是維護(hù)分支上工作時(shí),可以有個(gè)方便的地方對(duì)關(guān)于發(fā)布分支或是維護(hù)分支的問題進(jìn)行交流。

GitFlow 工作流中 Pull Request 的使用過程和上一節(jié)中完全一致:當(dāng)一個(gè)功能、發(fā)布或是熱修復(fù)分支需要 Review 時(shí),開發(fā)者簡單發(fā)起一個(gè) Pull Request,團(tuán)隊(duì)的其它成員會(huì)通過 Bitbucket 收到通知。
新功能一般合并到 develop 分支,而發(fā)布和熱修復(fù)則要同時(shí)合并到 develop 分支和 master 分支上。Pull Request 可能用做所有合并的正式管理。
在 Forking 工作流中使用 Pull Request
在 Forking 工作流中,開發(fā)者 push 完成的功能到他自己的倉庫中,而不是共享倉庫。然后,他發(fā)起一個(gè) Pull Request,讓項(xiàng)目維護(hù)者知道他的功能已經(jīng)可以 Review 了。
在這個(gè)工作流,Pull Request 的通知功能非常有用,因?yàn)轫?xiàng)目維護(hù)者不可能知道其它開發(fā)者在他們自己的倉庫添加了提交

由于各個(gè)開發(fā)有自己的公開倉庫,Pull Request 的源倉庫和目標(biāo)倉庫不是同一個(gè)。源倉庫是開發(fā)者的公開倉庫,源分支是包含了修改的分支。如果開發(fā)者要合并修改到正式代碼庫中,那么目標(biāo)倉庫是正式倉庫,目標(biāo)分支是 master 分支。
Pull Request 也可以用于正式項(xiàng)目之外的其它開發(fā)者之間的協(xié)作。比如,如果一個(gè)開發(fā)者和一個(gè)團(tuán)隊(duì)成員一起開發(fā)一個(gè)功能,他們可以發(fā)起一個(gè) Pull Request,用團(tuán)隊(duì)成員的 Bitbucket 倉庫作為目標(biāo),而不是正式項(xiàng)目的倉庫。然后使用相同的功能分支作為源和目標(biāo)分支。

2 個(gè)開發(fā)者之間可以在 Pull Request 中討論和開發(fā)功能。完成開發(fā)后,他們可以發(fā)起另一個(gè) Pull Request,請(qǐng)求合并功能到正式的 master 分支。在 Forking 工作流中,這樣的靈活性讓 Pull Request 成為一個(gè)強(qiáng)有力的協(xié)作工具。
示例
下面的示例演示了 Pull Request 如何在在 Forking 工作流中使用。也同樣適用于小團(tuán)隊(duì)的開發(fā)協(xié)作和第三方開發(fā)者向開源項(xiàng)目的貢獻(xiàn)。
在示例中,小紅是個(gè)開發(fā),小明是項(xiàng)目維護(hù)者。他們各自有一個(gè)公開的 Bitbucket 倉庫,而小明的倉庫包含了正式工程。
小紅 fork 正式項(xiàng)目

小紅先要 fork 小明的 Bitbucket 倉庫,開始項(xiàng)目的開發(fā)。她登陸 Bitbucket,瀏覽到小明的倉庫頁面,點(diǎn) Fork 按鈕。

然后為 fork 出來的倉庫填寫名字和描述,這樣小紅就有了服務(wù)端的項(xiàng)目拷貝了。
小紅克隆她的 Bitbucket 倉庫

下一步,小紅克隆自己剛才 fork 出來的 Bitbucket 倉庫,以在本機(jī)上準(zhǔn)備出工作拷貝。命令如下:
git clone https://user@bitbucket.org/user/repo.git
請(qǐng)記住,git clone 會(huì)自動(dòng)創(chuàng)建 origin 遠(yuǎn)程別名,是指向小紅 fork 出來的倉庫。
小紅開發(fā)新功能
在開始改代碼前,小紅要為新功能先新建一個(gè)新分支。她會(huì)用這個(gè)分支作為 Pull Request 的源分支。
git checkout -b some-feature
編輯代碼
git commit -a -m "Add first draft of some feature"
在新功能分支上,小紅按需要添加提交。甚至如果小紅覺得功能分支上的提交歷史太亂了,她可以用交互式 rebase 來刪除或壓制提交。對(duì)于大型項(xiàng)目,整理功能分支的歷史可以讓項(xiàng)目維護(hù)者更容易看出在 Pull Request 中做了什么內(nèi)容。
小紅 push 功能到她的 Bitbucket 倉庫中

小紅完成了功能后,push 功能到她自己的 Bitbucket 倉庫中(不是正式倉庫),用下面簡單的命令:
git push origin some-branch
這時(shí)她的變更可以讓項(xiàng)目維護(hù)者看到了(或者任何想要看的協(xié)作者)。
小紅發(fā)起 Pull Request

Bitbucket 上有了她的功能分支后,小紅可以用她的 Bitbucket 賬號(hào)瀏覽到她的 fork 出來的倉庫頁面,點(diǎn)右上角的【Pull Request】按鈕,發(fā)起一個(gè) Pull Request。彈出的表單自動(dòng)設(shè)置小紅的倉庫為源倉庫,詢問小紅以指定源分支、目標(biāo)倉庫和目標(biāo)分支。
小紅想要合并功能到正式倉庫,所以源分支是她的功能分支,目標(biāo)倉庫是小明的公開倉庫,而目標(biāo)分支是 master 分支。另外,小紅需要提供 Pull Request 的標(biāo)題和描述信息。如果需要小明以外的人審核批準(zhǔn)代碼,她可以把這些人填在【Reviewers】文本框中。

創(chuàng)建好了 Pull Request,通知會(huì)通過Bitbucket系統(tǒng)消息或郵件(可選)發(fā)給小明。
小明 review Pull Request

在小明的 Bitbucket 倉庫頁面的 【Pull Request】Tab 可以看到所有人發(fā)起的 Pull Request。點(diǎn)擊小紅的 Pull Request 會(huì)顯示出 Pull Request 的描述、功能的提交歷史和每個(gè)變更的差異(diff)。
如果小明想要合并到項(xiàng)目中,只要點(diǎn)一下【Merge】按鈕,就可以同意 Pull Request 并合并到 master 分支。
但如果像這個(gè)示例中一樣小明發(fā)現(xiàn)了在小紅的代碼中的一個(gè)小 Bug,要小紅在合并前修復(fù)。小明可以在整個(gè) Pull Request 上加上評(píng)注,或是選擇歷史中的某個(gè)提交加上評(píng)注。

小紅補(bǔ)加提交
如果小紅對(duì)反饋有任何疑問,可以在 Pull Request 中響應(yīng),把 Pull Request 當(dāng)作是她功能討論的論壇。
小紅在她的功能分支新加提交以解決代碼問題,并 push 到她的 Bitbucket 倉庫中,就像前一輪中的做法一樣。這些提交會(huì)進(jìn)入的 Pull Request,小明在原來的評(píng)注旁邊可以再次 review 變更。
小明接受 Pull Request
最終,小明接受變更,合并功能分支到 master 分支,并關(guān)閉 Pull Request。至此,功能集成到項(xiàng)目中,其它的項(xiàng)目開發(fā)者可以用標(biāo)準(zhǔn)的 git pull 命令 pull 這些變更到自己的本地倉庫中。
總結(jié)
到了這里,你應(yīng)該有了所有需要的工具來集成 Pull Request 到你自己的工作流。請(qǐng)記住,Pull Request 并不是為了替代任何基于 Git 的協(xié)作工作流,而是它們的一個(gè)便利的補(bǔ)充,讓團(tuán)隊(duì)成員間的協(xié)作更輕松方便。