4.1. Fork + Pull模式?參與GitHub中的項(xiàng)目開發(fā),最常用和推薦的首選方式是“Fork + Pull”模式。在“Fork + Pull”模式下,項(xiàng)目參與者不必向項(xiàng)目創(chuàng)建者申請?zhí)峤粰?quán)限,而是在自己的托管空間下建立項(xiàng)目的派生(Fork)。 如果一個(gè)開源項(xiàng)目派生出另外的項(xiàng)目,通常意味著項(xiàng)目的分裂和開發(fā)團(tuán)隊(duì)的削弱,而GitHub中的項(xiàng)目派生則不會,而且正好相反,GitHub中的項(xiàng)目派生是項(xiàng)目壯大的體現(xiàn)。所有的派生項(xiàng)目都會有鏈接指向原始項(xiàng)目,派生項(xiàng)目沒有獨(dú)立的缺陷追蹤系統(tǒng)(ISSUE),而是必須利用創(chuàng)建者本人的項(xiàng)目中的缺陷追蹤系統(tǒng)。至于在派生項(xiàng)目中創(chuàng)建的提交,可以非常方便地利用GitHub的Pull Request工具向原始項(xiàng)目的維護(hù)者發(fā)送Pull Request。 下面以GotGit版本庫為例,介紹如何利用GitHub提供的Fork和Pull Request工具實(shí)現(xiàn)工作協(xié)同。 4.1.1. 版本庫派生?GotGit版本庫[1]用于維護(hù)《Git權(quán)威指南》一書的官網(wǎng)和勘誤,下面演示的勘誤表修改是由王勝[2]通過GitHub之外的一個(gè)缺陷追蹤平臺報(bào)告的[3]。他在報(bào)告中,甚至直接用GNU diff格式告訴我該如何修改。 下面就以用戶gotgithub身份,訪問版本庫 https://github.com/gotgit/gotgit/ ,添加新的勘誤。如圖4-1所示,gotgit項(xiàng)目在之前的示例中已經(jīng)被我們關(guān)注但尚未Fork。 點(diǎn)擊項(xiàng)目名稱右側(cè)的Fork按鈕,便在gotgithub用戶自己的托管空間下創(chuàng)建項(xiàng)目派生,派生項(xiàng)目版本庫出現(xiàn)在版本庫列表中,如圖4-2。 訪問派生后的版本庫,會發(fā)現(xiàn)和派生前的幾乎相同,除了沒有缺陷跟蹤(ISSUE),以及標(biāo)識了該項(xiàng)目派生之前的原路徑等。如圖4-3所示。 現(xiàn)在gotgithub用戶就在本地派生的版本庫中提交。
訪問GitHub上的派生項(xiàng)目頁面,會看到以用戶whangsheng在master分支[5]創(chuàng)建的提交。如圖4-4所示。 4.1.2. Pull Request?那么如何能夠讓gotgit原始項(xiàng)目的創(chuàng)建者知道這個(gè)派生項(xiàng)目及新的提交呢?GitHub提供的工具就是“Pull Request”。注意到圖4-3右上方“Pull Request”按鈕了么?點(diǎn)擊該按鈕進(jìn)入Pull Request創(chuàng)建界面。 在彈出的Pull Request創(chuàng)建界面中,點(diǎn)擊菜單中的“Commits”,查看所包含的提交。如圖4-5所示。 點(diǎn)擊菜單中的“Files Changed”,查看所包含的提交。如圖4-6所示。 點(diǎn)擊菜單中的“Preview Discussion”,填寫Pull Request的標(biāo)題和內(nèi)容,完成Pull Request的創(chuàng)建。如圖4-7所示。 當(dāng)Pull Request發(fā)出后,項(xiàng)目gotgit的開發(fā)者會收到通知郵件,如圖4-8所示。 點(diǎn)擊郵件中的URL鏈接,以項(xiàng)目gotgit的開發(fā)者(如ossxp-com)身份登錄,看到如圖4-9的視圖。之所以看到有兩個(gè)用戶參與到此Pull Request,是因?yàn)镻ull Request創(chuàng)建者和提交的作者是不同的用戶。圖4-9下方的表單可以向Pull Request追加評論,或者關(guān)閉此Pull Request。 GitHub如果檢測到Pull Request中包含的提交可以直接合并,會顯示自動合并的提示信息,點(diǎn)擊圖4-9中提示信息中的自動合并按鈕,顯示圖4-10的自動合并對話框。 點(diǎn)擊“Confirm Merge”按鈕即完成Pull Request中所含提交的自動合并。自動合并完成后,Pull Request頁面下方會以評論的形式出現(xiàn)相關(guān)提示,并自動關(guān)閉Pull Request。如圖4-11所示。 4.1.3. 手工合并?Pull Request提供的自動合并顯示在提交日志中是什么樣子的呢?以用戶ossxp-com身份檢出版本庫,會看到用戶wangsheng的提交已經(jīng)合并到版本庫中。 $ git clone git@github.com:gotgit/gotgit.git
$ cd gotgit
$ git log --graph -3
* commit 6c1f1ee152629fd2f8d00ebe92c27a32d068d756
|\ Merge: 00c6c4b 7ecdfe7
| | Author: OpenSourceXpress <worldhello.net@gmail.com>
| | Date: Tue Aug 16 01:23:47 2011 -0700
| |
| | Merge pull request #4 from gotgithub/master
| |
| | Find a typo in the book
| |
| * commit 7ecdfe7451412cfb2e65bb47c12cf2162e21c841
|/ Author: Wang Sheng <wangsheng@>
| Date: Tue Aug 16 10:17:53 2011 +0800
|
| Fixed #3: should be 項(xiàng)目, not 項(xiàng).
|
* commit 00c6c4bfab9824bd967440902ce87440f9e87852
| Author: Jiang Xin <worldhello.net@gmail.com>
| Date: Wed Aug 3 11:50:31 2011 +0800
|
| Change font color for stronger text from red to brown.
可以看出GitHub的自動合并產(chǎn)生了一個(gè)合并提交,類似執(zhí)行git merge --no-ff命令。也就是說即使用戶wangsheng的提交是一個(gè)“快進(jìn)式提交”(基于gotgit/gotgit版本庫最新提交所做的提交),也要產(chǎn)生一個(gè)合并提交。 可能有人并不喜歡這種用--no-ff參數(shù)的非標(biāo)準(zhǔn)的合并方式,因?yàn)檫@種合并產(chǎn)生了一個(gè)多余的提交,可能增加代碼評審的負(fù)擔(dān)。若要取消GitHub的自動合并也很簡單,因?yàn)镚it無所不能: $ git reset --hard HEAD^ # 回退一個(gè)提交,即回退到當(dāng)前提交的第一個(gè)父提交
$ git rev-parse HEAD # 檢查是否正確的回退
00c6c4bfab9824bd967440902ce87440f9e87852
$ git push -f # 強(qiáng)制推送回退的 master 分支
下面就演示一下當(dāng)收到他人的Pull Request后,該如何手動合并。實(shí)際上在很多情況下,Pull Request所含提交有可能造成合并沖突,那樣的話GitHub不再、也不能提供自動合并功能,就必須采用手工合并的方式。
4.1.4. 在線編輯?GitHub提供了在線編輯功能,這樣可以無需克隆版本庫、無需使用Git即可完成對版本庫中文件的修改,甚至可以在你的iPad甚至iPhone上完成對文件的修改。 以gotgithub賬戶身份登錄GitHub,訪問之前派生而來的版本庫gotgithub/gotgit中的文件,例如文件errata.md[6],會看到其中一個(gè)“Edit this file”的按鈕,如圖4-12所示。 點(diǎn)擊圖4-12中的“Edit this file”按鈕,開始在線編輯文件errata.md,編輯器還支持語法加亮,如圖4-13所示。 4.1.5. 簡化的 Fork + Pull Request?到目前,我們已經(jīng)了解了GitHub的三大武器:Fork、Pull Request和在線編輯。對于最常用的“Fork + Pull Request”操作,GitHub還提供了一個(gè)快捷模式。即GitHub對于無權(quán)更改的他人版本庫中的文件,提供了一個(gè)類似在線編輯的按鈕,名為“Fork and edit this file”按鈕,自動完成版本庫派生和在線編輯,即將三大武器一勺燴。 訪問他人版本庫(尚未在自己空間派生)中的文件,例如訪問下面地址:http:///hello-world-makefile[7]。顯示他人(ossxp-com)版本庫hello-world中的src/Makefile文件,如圖4-14所示。 點(diǎn)擊圖4-14中的“Fork and edit this file”按鈕,會自動在自己托管空間創(chuàng)建派生版本庫,并開始在線編輯文件src/Makefile,如圖4-15所示。 文件修改完畢,點(diǎn)擊“Propose File Change”按鈕,會將改動作提交到派生的版本庫中,并馬上開啟一個(gè)新的Pull Request。如圖4-16所示。 點(diǎn)擊“Send pull request”按鈕完成Pull Request的創(chuàng)建。如果仔細(xì)查看圖4-16,會發(fā)現(xiàn)Pull Request所包含的修改發(fā)生在gotgithub/hello-world派生版本庫中的patch-1分支中,并非通常的master分支。 原版本庫ossxp-com/hello-world的開發(fā)者會收到一封郵件,通知有新的Pull Request,如下所示(前四行為信頭): From: GotGitHub <reply+i-...@reply.github.com>
Date: 2011/12/17
Subject: [hello-world] Bugfix: build target when version.h changed. (#1)
To: Jiang Xin <worldhello.net@gmail.com>
Without this fix, when version changed only version.h update, target rebuild needs a second `make`.
You can merge this Pull Request by running:
git pull https://github.com/gotgithub/hello-world patch-1
Or you can view, comment on it, or merge it online at:
https://github.com/ossxp-com/hello-world/pull/1
-- Commit Summary --
* Bugfix: build target when version.h changed.
-- File Changes --
M src/Makefile (3)
-- Patch Links --
https://github.com/ossxp-com/hello-world/pull/1.patch
https://github.com/ossxp-com/hello-world/pull/1.diff
---
Reply to this email directly or view it on GitHub:
https://github.com/ossxp-com/hello-world/pull/1
版本庫ossxp-com/hello-world的管理員既可以通過GitHub提供的圖形化界面完成對 Pull Request 的審核和合并,也可以在命令行下完成。正如郵件中所述若使用命令行,操作如下: $ git pull https://github.com/gotgithub/hello-world patch-1
|
|