← 上一章:【常見問題】Clone 跟 Pull 指令有什麼不一樣? 下一章:【狀況題】怎麼跟上當初 fork 專案的進度? →


與其它開發者的互動 - 使用 Pull Request(PR)

在 GitHub 上,有非常多的開源專案,有些專案你很有興趣,也很想幫忙、貢獻一己之力,於是你可能寫信或傳訊息給專案的原作說「我覺得你的專案很有趣,開個權限給我吧,我來幫你加一些功能」。想想看,如果你是原作者,有個不知道哪裡來的人叫你開權限給他,你願意嗎?

在 GitHub 上有個有趣的機制:

  1. 先複製(Fork)一份原作的專案到你自己的 GitHub 帳號底下。
  2. 因為這個複製回來的專案已經在你自己的 GitHub 帳號下,所以你就有完整的權限,想怎麼改就怎麼改。
  3. 改完後,先推回(Push)你自己帳號的專案。
  4. 然後發個通知,讓原作者知道你有幫忙做了一些事情,請他看一下。
  5. 原作者看完後說「我覺得可以」,然後就決定把你做的這些修改合併(Merge)到他的專案裡。

其中,第 4 步的那個「通知」,就是發一個請原作來拉回去(Pull)的請求(Request),稱之 Pull Request,簡稱 PR。

小提示

Fork 這個字在這邊翻譯成「複製」並不是這個字的原意,Fork 的中文翻譯是「分叉」、「叉子」,在技術圈來說這個詞使用的情境是「原作的做的不夠好,其它人覺得可以做得更好或是想加入一些個人喜好的功能而修改出另外的版本」,大概就是漫畫與同人誌差不多的概念吧。不過為了讓大家比較容易理解,這裡還是會使用「複製」做為 Fork 的翻譯。

實際演練

前情提要

來實際演練一下,不過因為這個演練自己一個人來,所以得要開另一隻分身來模擬一下:

  • 專案網址:https://github.com/kaochenlong/dummy-git
  • 角色 A,也就是專案的原作者:https://github.com/kaochenlong
  • 角色 B,就是想要幫忙的路人:https://github.com/eddiekao

第一步:複製(Fork)專案

角色 B,先到專案網址的頁面,看一下右上角的那排按鈕:

pull request

這三個按鈕的功能分別是「Watch(關注)」、「Star(給星星)」以及「Fork(複製一份到你的帳號)」,請按下 Fork 按鈕,接著會看到一個像影印機的畫面:

pull request

表示正在把原作的專案,複製一份到你的帳號底下。完成後,注意看一下畫面的左上角:

pull request

現在這個專案的確是已經放到角色 B 的帳號下,而且標註「Forked from…」是來自角色 A。這也表示,你對放在自己帳號底下的這個專案有完整的存取權限了。

第二步:Clone 回來修改

如果忘記 Clone 指令,請見「從伺服器上取得 Repository」章節介紹。

$ git clone https://github.com/eddiekao/dummy-git.git
Cloning into 'dummy-git'...
remote: Counting objects: 47, done.
remote: Total 47 (delta 0), reused 0 (delta 0), pack-reused 47
Unpacking objects: 100% (47/47), done.

要確認 Clone 的網址是角色 B 的專案,不要 Clone 錯了。

接著就是開始進行修改,例如我在 index.html 檔案加上了一行「Git is a good tool for every developer :)」。接著就是一般的 Git Commit 動作了:

$ git add index.html

$ git commit -m "update index"
[master ac341ae] update index
 1 file changed, 1 insertion(+)

忘記怎麼使用 git add 或是 git commit 的話,可參閱「把檔案交給 Git 控管」章節說明。

第三步:Push 回你自己的專案

因為剛剛我們是用 Clone 下來的,Clone 會自動幫我們設定好 upstream,所以接下來只要執行 git push 指令而不需另外指定參數:

$ git push
Username for 'https://github.com': eddiekao
Password for 'https://eddiekao@github.com':
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 385 bytes | 385.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/eddiekao/dummy-git.git
   fd7cd38..ac341ae  master -> master

因為我是選用 HTTPS 的方式,所以需要輸入 GitHub 的使用者帳號及密碼。忘記怎麼 Push 的話,可參考「Push 上傳到 GitHub」章節。

第四步:發 PR 給原作者

回到自己的專案頁面,可以找到一個「New pull request」的按鈕:

pull request

按下「Create pull request」後,可開始填寫 PR 的相關資訊,讓作者知道你這個 PR 大概做了什麼事:

pull request

在這裡可以選擇要發 PR 到原作的哪個分支:

pull request

填寫完畢後,按下「Create pull request」按鈕後,即算完成送出 PR:

pull request

第五步:原作收下 PR

切換回角色 A,也就是原作者,便可以在專案的頁面看到 Pull requests 的數量增加了:

pull request

點進去看細節,可以看到這包 PR 做了哪些修改:

pull request

如果覺得可以收,就只要按下 Merge pull request 按鈕後,就會合併這次的 Commit:

pull request

發送 PR,原作確認沒問題就收下來,這種發 PR 的方式,在開源界是很常見的貢獻程式碼的方法。

應用情境

不只在開源專案,即使在企業內部的專案也適合使用發 PR 的方式來進行開發。在開發產品的時候,通常會挑選固定一個分支做為可以上線的正式版本分支,慣例常會使用 master 或是 production 分支做為正式分支。當越多人參與同一個專案,讓每個人都可以 Commit 到專案正式上線的分支不是個好的做法,這時候便可使用 PR 方式來進行。

每位開發者都先從公司的專案 Fork 一份到自己的帳號下,待功能完成後再發 PR 回公司的專案。負責管理這個專案的人收到 PR 後,進行 Code Review 並確認無誤後便可進行合併,這樣一來可讓這個產品分支處於隨時都是可上線的狀態。

也許一開始會覺得這樣很麻煩,但隨著越多人一起協同開發,就越需要訂定規則,在後面 Git Flow 章節所要介紹的也是其中一款開發流程。


← 上一章:【常見問題】Clone 跟 Pull 指令有什麼不一樣? 下一章:【狀況題】怎麼跟上當初 fork 專案的進度? →

Comments