1. 首先 “Fork” 他人的 repository(代碼倉(cāng)庫(kù))
? ? ? ?“Fork” 的名詞是 “叉子” 的意思,不過(guò)這里取的是動(dòng)詞 “分叉,建一個(gè)分支” 的意思。進(jìn)入你想?yún)⑴c合作開(kāi)發(fā)的倉(cāng)庫(kù)界面,點(diǎn)擊右上角的?“Fork”?圖標(biāo),此時(shí)你已經(jīng)復(fù)制了一個(gè)副本在你的 GitHub 倉(cāng)庫(kù)中了,或者是說(shuō)一個(gè)新的代碼倉(cāng)庫(kù)被創(chuàng)建了,可以打開(kāi)你的 GitHub 主頁(yè)看一看。
? ? ? ?注意,這個(gè)遠(yuǎn)程倉(cāng)庫(kù)是屬于你自己的。這里 “Fork” 不同于 “Clone”,“Clone” 是發(fā)生在你的本地機(jī)器中,相當(dāng)于你復(fù)制了一個(gè)完全相同的副本在你的終端上,但該副本的遠(yuǎn)程倉(cāng)庫(kù)連接的仍然是原作者的倉(cāng)庫(kù),所以你并不是這個(gè)項(xiàng)目倉(cāng)庫(kù)的擁有者,沒(méi)有更新它的權(quán)限。
? ? ? ?因此,“Fork” 正是我們所需要的。

? ? ? ? 點(diǎn)擊之后可以看到,自己帳號(hào)內(nèi)有一個(gè)新的代碼倉(cāng)庫(kù)被創(chuàng)建了。

? ? ? 然后將這個(gè)代碼倉(cāng)庫(kù) “Clone”(克?。┑侥愕谋镜貦C(jī)器中,可以使用命令行或者 IDE(比如 Intellij IDEA)的?VCS?功能來(lái)實(shí)現(xiàn)。“Clone”?成功之后你就可以自主修改里面的內(nèi)容,然后?“Push”?到遠(yuǎn)程倉(cāng)庫(kù)中,注意,這是你自己的遠(yuǎn)程倉(cāng)庫(kù)。但是不使用 “Fork”,而是直接 “Clone”(克隆)原作者的倉(cāng)庫(kù)的話,你會(huì)得到一個(gè) “fatal: unable to access” 的提示,無(wú)法訪問(wèn)。
? ? ? ?在這一環(huán)節(jié),所有的修改只發(fā)生在你的遠(yuǎn)程倉(cāng)庫(kù)中,原作者的代碼倉(cāng)庫(kù)內(nèi)容是不會(huì)發(fā)生任何改變的。這里最需要理解的是,“Clone” 下來(lái)的本地倉(cāng)庫(kù)連接的是你 GitHub 上的遠(yuǎn)程倉(cāng)庫(kù)。
2. 開(kāi)始參與開(kāi)發(fā)前的一些準(zhǔn)備
(1)在你做任何開(kāi)發(fā)前,最好先詳細(xì)閱讀該項(xiàng)目的?CONTRIBUTING.md 文件。
(2)瀏覽該項(xiàng)目的?Issues(問(wèn)題)公告,甚至可以自己創(chuàng)建一個(gè)?Issue。
(3)一般不要將自己做的修改提交到?master branch(主分支)上,而是應(yīng)該提交到某個(gè)明確的?topic branch(主題分支,解決某個(gè)bug或者添加某一功能的分支)上。注意,我們應(yīng)該自己建一個(gè) topic branch,然后在上面作修改,而不在 master 分支直接修改,因?yàn)檫@樣更具有直觀性。
(4)最好每次只提交較小的修改,并寫(xiě)好清晰明確的?Commit Messages(提交說(shuō)明).
(5)如果有需要,請(qǐng)更新?README 文件。
3. 創(chuàng)建一個(gè) Pull Request
? ? ? ?按自己的需要去修改項(xiàng)目?jī)?nèi)容,然后將所做的修改提交(Add+Commit)到自己的代碼倉(cāng)庫(kù),接著到倉(cāng)庫(kù)頁(yè)面,點(diǎn)擊?New pull request?按鈕。

? ? ? ?點(diǎn)擊去之后可以看到,左邊紅框是你 “Fork” 的原項(xiàng)目倉(cāng)庫(kù)和分支,右邊紅框是你當(dāng)前選擇的項(xiàng)目倉(cāng)庫(kù)和分支。其實(shí)這里就是將兩個(gè)紅框內(nèi)的內(nèi)容作對(duì)比,并把不相同的地方顯示出來(lái)。因?yàn)榇藭r(shí)兩個(gè)倉(cāng)庫(kù)和分支的內(nèi)容是完全一樣的,所有沒(méi)有什么信息顯示出來(lái)(我沒(méi)有做修改)。不太理解的話,可以自由去嘗試四個(gè)下拉框里不同的選項(xiàng),很快你就會(huì)知道是怎么回事了。

? ? ? ?我這里任意選擇了原項(xiàng)目的另一個(gè)分支,因?yàn)檫@兩個(gè)分支不完全相同,所以可以看到出現(xiàn)了一個(gè)?“Create pull request”?的按鈕,點(diǎn)擊它。

? ? ? ?填寫(xiě)你的請(qǐng)求信息,說(shuō)明你做了些什么之類(lèi)的。這個(gè)請(qǐng)求是發(fā)給該項(xiàng)目的維護(hù)者(擁有者)的,完成之后點(diǎn)擊?“Create pull request”?按鈕即可。

? ? ? ?之后項(xiàng)目的維護(hù)者會(huì)受到你的請(qǐng)求,只要他/她通過(guò)了你的請(qǐng)求,你所做的修改就會(huì)被整合到原項(xiàng)目的倉(cāng)庫(kù)里了。

左邊是你的本地倉(cāng)庫(kù),中間是你在 GitHub 上 Fork 建立的倉(cāng)庫(kù),右邊是項(xiàng)目的原倉(cāng)庫(kù)。
4. 與原倉(cāng)庫(kù)保持同步更新
? ? ? ?說(shuō)到合作開(kāi)發(fā)就會(huì)有一個(gè)問(wèn)題,如何與他人的代碼保持同步?在自己做開(kāi)發(fā)的過(guò)程中,難免會(huì)遇到你 “Fork” 的項(xiàng)目已經(jīng)有了新的更新,這時(shí)當(dāng)然是希望自己倉(cāng)庫(kù)中的代碼也能同步進(jìn)行更新。可是,你本地倉(cāng)庫(kù)所連接的遠(yuǎn)程倉(cāng)庫(kù)的是你自己的 GitHub 倉(cāng)庫(kù),而不是原作者的倉(cāng)庫(kù)。解決方法其實(shí)很簡(jiǎn)單,為你的本地倉(cāng)庫(kù)再添加一個(gè)遠(yuǎn)程倉(cāng)庫(kù)源。
查看當(dāng)前項(xiàng)目所連接的遠(yuǎn)程倉(cāng)庫(kù)
打開(kāi)終端,進(jìn)入到項(xiàng)目的 Git 倉(cāng)庫(kù)所在目錄,一般就是項(xiàng)目目錄,輸入:
git remote -v

? ? ? 可以看到目前只連接了我自己的遠(yuǎn)程倉(cāng)庫(kù)。
添加原作者的遠(yuǎn)程倉(cāng)庫(kù)連接
git remote add upstream https://github.com/GoogleChrome/lighthouse.git
(注意替換原倉(cāng)庫(kù)的 http 鏈接)

? ? ? 如圖,現(xiàn)在已經(jīng)成功添加原項(xiàng)目的遠(yuǎn)程倉(cāng)庫(kù)了。
還差一點(diǎn)就大功告成了
(1)從原倉(cāng)庫(kù)獲取最新版本到本地
git fetch upstream master
(2)保證當(dāng)前位于 master 分支上
git checkout master
(3)將最新版本整合到本地 master 分支上
git merge upstream/master
(4)將更新發(fā)送到自己的 GitHub 倉(cāng)庫(kù)里
git push origin master
(1)(2)(3)步可以用
git pull upstream master
這條命令替代,可以這樣不太安全,因?yàn)槟?fetch(獲取)之后可以通過(guò)
gitlog--oneline --graph --decorate --all
來(lái)查看更新的情況,再?zèng)Q定是否?merge(整合)到一起。
