現(xiàn)在我們可以很方便地向一個(gè)項(xiàng)目貢獻(xiàn)內(nèi)容,來看一下另一個(gè)方面的內(nèi)容:創(chuàng)建、維護(hù)和管理你自己的項(xiàng)目。
讓我們創(chuàng)建一個(gè)版本庫來分享我們的項(xiàng)目。 通過點(diǎn)擊面板右側(cè)的“New repository”按鈕,或者頂部工具條你用戶名旁邊的 + 按鈕來開始我們的旅程。 參見 Figure 6-30。
http://wiki.jikexueyuan.com/project/pro-git-two/images/114.png" alt="" />
Figure 6-29. 這是 “Your repositories”區(qū)域.
http://wiki.jikexueyuan.com/project/pro-git-two/images/115.png" alt="" />
Figure 6-30. 這是 “New repository” 下拉列表. 這會(huì)帶你到 “new repository” 表單:
http://wiki.jikexueyuan.com/project/pro-git-two/images/116.png" alt="" />
Figure 6-31. 這是 “new repository” 表單.
這里除了一個(gè)你必須要填的項(xiàng)目名,其他字段都是可選的。 現(xiàn)在只需要點(diǎn)擊 “Create Repository” 按鈕,Duang!!! – 你就在 GitHub 上擁有了一個(gè)以
因?yàn)槟壳皶簾o代碼,GitHub 會(huì)顯示有關(guān)創(chuàng)建新版本庫或者關(guān)聯(lián)到一個(gè)已有的 Git 版本庫的一些說明。 我們不會(huì)在這里詳細(xì)說明此項(xiàng),如果你需要復(fù)習(xí),去看 Git 基礎(chǔ)。
現(xiàn)在你的項(xiàng)目就托管在 GitHub 上了,你可以把 URL 給任何你想分享的人。 GitHub 上的項(xiàng)目可通過 HTTP 或 SSH 訪問,格式是:HTTP : https://github.com/
Note
通常對(duì)于公開項(xiàng)目可以優(yōu)先分享基于 HTTP 的 URL,因?yàn)橛脩艨寺№?xiàng)目不需要有一個(gè) GitHub 帳號(hào)。 如果你分享 SSH URL,用戶必須有一個(gè)帳號(hào)并且上傳 SSH 密鑰才能訪問你的項(xiàng)目。 HTTP URL 與你貼到瀏覽器里查看項(xiàng)目用的地址是一樣的。
如果你想與他人合作,并想給他們提交的權(quán)限,你需要把他們添加為 “Collaborators”。 如果 Ben,Jeff,Louise 都在 GitHub 上注冊(cè)了,你想給他們推送的權(quán)限,你可以將他們添加到你的項(xiàng)目。 這樣做會(huì)給他們 “推送” 權(quán)限,就是說他們對(duì)項(xiàng)目和 Git 版本庫都有讀寫的權(quán)限。
點(diǎn)擊邊欄底部的 “Settings” 鏈接。
http://wiki.jikexueyuan.com/project/pro-git-two/images/117.png" alt="" />
Figure 6-32. 版本庫設(shè)置鏈接. 然后從左側(cè)菜單中選擇 “Collaborators” 。 然后,在輸入框中填寫用戶名,點(diǎn)擊 “Add collaborator.” 如果你想授權(quán)給多個(gè)人,你可以多次重復(fù)這個(gè)步驟。 如果你想收回權(quán)限,點(diǎn)擊他們同一行右側(cè)的 “X”
http://wiki.jikexueyuan.com/project/pro-git-two/images/118.png" alt="" />
Figure 6-33. 版本庫合作者.
現(xiàn)在你有一個(gè)包含一些代碼的項(xiàng)目,可能還有幾個(gè)有推送權(quán)限的合作者,下面來看當(dāng)你收到合并請(qǐng)求時(shí)該做什么。
合并請(qǐng)求可以來自倉庫副本的一個(gè)分支,或者同一倉庫的另一個(gè)分支。 唯一的區(qū)別是 fork 過來的通常是和你不能互相推送的人,而內(nèi)部的推送通常都可以互相訪問。
作為例子,假設(shè)你是 “tonychacon” ,你創(chuàng)建了一個(gè)名為 “fade” 的 Arduino 項(xiàng)目.
有人來修改了你的代碼,給你發(fā)了一個(gè)合并請(qǐng)求。 你會(huì)收一封關(guān)于合并請(qǐng)求的提醒郵件,它看起來像 Figure 6-34。
http://wiki.jikexueyuan.com/project/pro-git-two/images/119.png" alt="" />
Figure 6-34. 新的合并請(qǐng)求的郵件通知. 關(guān)于這個(gè)郵件有幾個(gè)要注意的地方。 它會(huì)給你一個(gè)小的變動(dòng)統(tǒng)計(jì)結(jié)果?—?一個(gè)包含合并請(qǐng)求中改變的文件和改變了多少的列表。 它還給你一個(gè) GitHub 上進(jìn)行合并請(qǐng)求操作的鏈接。 還有幾個(gè)可以在命令行使用的 URL。
如果你注意到 git pull
還有一些有趣的 URL,像 .diff 和 .patch ,就像你猜的那樣,它們提供 diff 和 patch 的標(biāo)準(zhǔn)版本。 你可以技術(shù)性地用下面的方法合并“合并請(qǐng)求”:
$ curl http://github.com/tonychacon/fade/pull/1.patch | git am
就像我們?cè)?GitHub 流程,_ 說過的,現(xiàn)在你可以跟開啟合并請(qǐng)求的人進(jìn)行會(huì)話。 你既可以對(duì)某些代碼添加注釋,也可以對(duì)整個(gè)提交添加注釋或?qū)φ麄€(gè)合并請(qǐng)求添加注釋,在任何地方都可以用 GitHub Flavored Markdown。
每次有人在合并請(qǐng)求上進(jìn)行注釋你都會(huì)收到通知郵件,通知你哪里發(fā)生改變。 他們都會(huì)包含一個(gè)到改變位置的鏈接,你可以直接在郵件中對(duì)合并請(qǐng)求進(jìn)行注釋。
http://wiki.jikexueyuan.com/project/pro-git-two/images/120.png" alt="" />
Figure 6-35. Responses to emails are included in the thread.
一旦代碼符合了你的要求,你想把它合并進(jìn)來,你可以把代碼拉取下來在本地進(jìn)行合并,也可以用我們之前提到過的 git pull
對(duì)于很瑣碎的合并,你也可以用 GitHub 網(wǎng)站上的 “Merge” 按鈕。 它會(huì)做一個(gè) “non-fast-forward” 合并,即使可以快進(jìn)(fast-forward)合并也會(huì)產(chǎn)生一個(gè)合并提交記錄。 就是說無論如何,只要你點(diǎn)擊 merge 按鈕,就會(huì)產(chǎn)生一個(gè)合并提交記錄。 你可以在 Figure 6-36 看到,如果你點(diǎn)擊提示鏈接,GitHub 會(huì)給你所有的這些信息。
http://wiki.jikexueyuan.com/project/pro-git-two/images/121.png" alt="" />
Figure 6-36. 合并按鈕和手工合并一個(gè)合并請(qǐng)求的指令. 如果你決定不合并它,你可以把合并請(qǐng)求關(guān)掉,開啟合并請(qǐng)求的人會(huì)收到通知。
如果你正在處理 許多 合并請(qǐng)求,不想添加一堆 remote 或者每次都要做一次拉取,這里有一個(gè)可以在 GitHub 上用的小技巧。 這是有點(diǎn)高級(jí)的技巧,但它相當(dāng)有用,我們會(huì)在 引用規(guī)格 有更多的細(xì)節(jié)說明。
實(shí)際上 GitHub 在服務(wù)器上把合并請(qǐng)求分支視為一種 “假分支”。 默認(rèn)情況下你克隆時(shí)不會(huì)得到它們,但它們還是隱式地存在,你可以很容易地訪問到它們。
為了展示這個(gè),我們要用到一個(gè)叫做 ls-remote 的低級(jí)命令(通常被叫做“plumbing”,我們會(huì)在 底層命令和高層命令 讀到更多相關(guān)內(nèi)容)。 這個(gè)命令在日常 Git 操作中基本不會(huì)用到,但在顯示服務(wù)器上有哪些引用(reference)時(shí)很管用。
如果在我們之前用過的 “blink” 版本庫上使用這個(gè)命令,我們會(huì)得到一個(gè)版本庫里所有的分支,標(biāo)簽和其它引用(reference)的列表。
$ git ls-remote https://github.com/schacon/blink
10d539600d86723087810ec636870a504f4fee4d HEAD
10d539600d86723087810ec636870a504f4fee4d refs/heads/master
6a83107c62950be9453aac297bb0193fd743cd6e refs/pull/1/head
afe83c2d1a70674c9505cc1d8b7d380d5e076ed3 refs/pull/1/merge
3c8d735ee16296c242be7a9742ebfbc2665adec1 refs/pull/2/head
15c9f4f80973a2758462ab2066b6ad9fe8dcf03d refs/pull/2/merge
a5a7751a33b7e86c5e9bb07b26001bb17d775d1a refs/pull/4/head
31a45fc257e8433c8d8804e3e848cf61c9d3166c refs/pull/4/merge
當(dāng)然,如果你在你自己的版本庫或其它你想檢查的遠(yuǎn)程版本庫中使用 git ls-remote origin ,它會(huì)顯示相似的內(nèi)容。
如果版本庫在 GitHub 上并且有打開的合并請(qǐng)求,你會(huì)得到一些以 refs/pull/ 開頭的引用。 它們實(shí)際上是分支,但因?yàn)樗鼈儾辉?refs/heads/ 中,所以正常情況下你克隆時(shí)不會(huì)從服務(wù)器上得到它們?—?抓取過程正常情況下會(huì)忽略它們。
每個(gè)合并請(qǐng)求有兩個(gè)引用 - 其中以 /head 結(jié)尾的引用指向的提交記錄與合并請(qǐng)求分支中的最后一個(gè)提交記錄是同一個(gè)。 所以如果有人在我們的版本庫中開啟了一個(gè)合并請(qǐng)求,他們的分支叫做 bug-fix,指向 a5a775 這個(gè)提交記錄,那么在 我們的 版本庫中我們沒有 bug-fix 分支(因?yàn)槟鞘窃谒麄兊?fork 中),但我們 可以 有一個(gè) pull/<pr#>/head 指向 a5a775。 這意味著我們可以很容易地拉取每一個(gè)合并請(qǐng)求分支而不用添加一堆 remote。
現(xiàn)在,你可以像直接抓取引用一樣抓取那些分支或提交。
$ git fetch origin refs/pull/958/head
From https://github.com/libgit2/libgit2
* branch refs/pull/958/head -> FETCH_HEAD
這告訴 Git: “連接到 origin 這個(gè) remote,下載名字為 refs/pull/958/head 的引用?!?Git 高高興興去執(zhí)行,下載構(gòu)建那個(gè)引用需要的所有內(nèi)容,然后把指針指向 .git/FETCH_HEAD 下面你想要的提交記錄。 然后你可以用 git merge FETCH_HEAD 把它合并到你想進(jìn)行測(cè)試的分支,但那個(gè)合并的提交信息看起來有點(diǎn)怪。 然而,如果你需要審查 一大批 合并請(qǐng)求,這樣操作會(huì)很麻煩。
還有一種方法可以抓取 所有的 合并請(qǐng)求,并且在你連接到遠(yuǎn)程(remote)的時(shí)候保持更新。 用你最喜歡的編輯器打開 .git/config ,查找 origin 遠(yuǎn)程(remote)。 看起來差不多像下面這樣:
[remote "origin"]
url = https://github.com/libgit2/libgit2
fetch = +refs/heads/*:refs/remotes/origin/*
以 fetch = 開頭的行是一個(gè) “refspec.” 它是一種把 remote 的名稱映射到你本地 .git 目錄的方法。 這一條(就是上面的這一條)告訴 Git,“remote 上 refs/heads 下面的內(nèi)容在我本地版本庫中都放在 refs/remotes/origin 。” 你可以把這一段修改一下,添加另一個(gè) refspec:
[remote "origin"]
url = https://github.com/libgit2/libgit2.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
最后一行告訴 Git: “所有看起來像 refs/pull/123/head 的引用應(yīng)該在本地版本庫像 refs/remotes/origin/pr/123 一樣存儲(chǔ)” 現(xiàn)在,如果你保存那個(gè)文件,執(zhí)行 git fetch:
$ git fetch
# …
* [new ref] refs/pull/1/head -> origin/pr/1
* [new ref] refs/pull/2/head -> origin/pr/2
* [new ref] refs/pull/4/head -> origin/pr/4
# …
現(xiàn)在所有的合并請(qǐng)求在本地像分支一樣展現(xiàn),它們是只讀的,當(dāng)你執(zhí)行抓取時(shí)它們也會(huì)更新。 這讓在本地測(cè)試合并請(qǐng)求中的代碼變得超級(jí)簡單:
$ git checkout pr/2
Checking out files: 100% (3769/3769), done.
Branch pr/2 set up to track remote branch pr/2 from origin.
Switched to a new branch 'pr/2'
你的鷹眼系統(tǒng)會(huì)發(fā)現(xiàn)在 refspec 的 remote 部分的結(jié)尾有個(gè) head 。 在 GitHub 那邊也有一個(gè) refs/pull/#/merge 引用,它代表的是如果你在網(wǎng)站上按了 “merge” 按鈕對(duì)應(yīng)的提交記錄。 這甚至讓你可以在按按鈕之前就測(cè)試這個(gè)合并。
你不僅可以在主分支或者說 master 分支上開啟合并請(qǐng)求,實(shí)際上你可以在網(wǎng)絡(luò)上的任何一個(gè)分支上開啟合并請(qǐng)求。 其實(shí),你甚至可以在另一個(gè)合并請(qǐng)求上開啟一個(gè)合并請(qǐng)求。
如果你看到一個(gè)合并請(qǐng)求在向正確的方向發(fā)展,然后你想在這個(gè)合并請(qǐng)求上做一些修改或者你不太確定這是個(gè)好主意,或者你沒有目標(biāo)分支的推送權(quán)限,你可以直接在合并請(qǐng)求上開啟一個(gè)合并請(qǐng)求。
當(dāng)你開啟一個(gè)合并請(qǐng)求時(shí),在頁面的頂端有一個(gè)框框顯示你要合并到哪個(gè)分支和你從哪個(gè)分支合并過來的。 如果你點(diǎn)擊那個(gè)框框右邊的 “Edit” 按鈕,你不僅可以改變分支,還可以選擇哪個(gè) fork。
http://wiki.jikexueyuan.com/project/pro-git-two/images/122.png" alt="" />
Figure 6-37. 手工修改合并請(qǐng)求的目標(biāo). 這里你可以很簡單地指明合并你的分支到哪一個(gè)合并請(qǐng)求或 fork。
GitHub 內(nèi)置了一個(gè)很好的通知系統(tǒng),當(dāng)你需要與別人或別的團(tuán)隊(duì)交流時(shí)用起來很方便。
在任何評(píng)論中你可以先輸入一個(gè)@,系統(tǒng)會(huì)自動(dòng)補(bǔ)全項(xiàng)目中合作者或貢獻(xiàn)者的名字和用戶名。
http://wiki.jikexueyuan.com/project/pro-git-two/images/123.png" alt="" />
Figure 6-38. 輸入 @ 來提醒某人. 你也可以提醒不在列表中的用戶,但是通常自動(dòng)補(bǔ)全用起更快。
當(dāng)你發(fā)布了一個(gè)帶用戶提醒的評(píng)論,那個(gè)用戶會(huì)收到通知。 這意味著把人們拉進(jìn)會(huì)話中要比讓他們投票有效率得多。 對(duì)于 GitHub 上的合并請(qǐng)求,人們經(jīng)常把他們團(tuán)隊(duì)或公司中的其它人拉來審查問題或合并請(qǐng)求。
如果有人收到了合并請(qǐng)求或問題的提醒,他們會(huì)"訂閱"它,后面有新的活動(dòng)發(fā)生他們都會(huì)持續(xù)收到提醒。 如果你是合并請(qǐng)求或者問題的發(fā)起方你也會(huì)被訂閱上,比如你在關(guān)注一個(gè)版本庫或者你評(píng)論了什么東西。 如果你不想再收到提醒,在頁面上有個(gè) “Unsubscribe” 按鈕,點(diǎn)一下就不會(huì)再收到更新了。
http://wiki.jikexueyuan.com/project/pro-git-two/images/124.png" alt="" />
Figure 6-39. 取消訂閱一個(gè)問題或合并請(qǐng)求.
當(dāng)我們?cè)谶@提到特指 GitHub 的 “notifications” ,指的是當(dāng) GitHub 上有事件發(fā)生時(shí),它通知你的方式,這里有幾種不同的方式來配置它們。 如果你打開配置頁面的 “Notification center” 標(biāo)簽,你可以看到一些選項(xiàng)。
http://wiki.jikexueyuan.com/project/pro-git-two/images/125.png" alt="" />
Figure 6-40. 通知中心選項(xiàng). 有兩個(gè)選項(xiàng),通過"郵件(Email)"和通過"網(wǎng)頁(Web)",你可以選用一個(gè)或者都不選或者都選。
網(wǎng)頁通知只在 GitHub 上存在,你也只能在 GitHub 上查看。 如果你打開了這個(gè)選項(xiàng)并且有一個(gè)你的通知,你會(huì)在你屏幕上方的通知圖標(biāo)上看到一個(gè)小藍(lán)點(diǎn)。參見 Figure 6-41。
http://wiki.jikexueyuan.com/project/pro-git-two/images/126.png" alt="" />
Figure 6-41. 通知中心. 如果你點(diǎn)擊那個(gè)玩意兒,你會(huì)看到你被通知到的所有條目,按照項(xiàng)目分好了組。 你可以點(diǎn)擊左邊欄的項(xiàng)目名字來過濾項(xiàng)目相關(guān)的通知。 你可以點(diǎn)擊通知旁邊的對(duì)號(hào)圖標(biāo)把通知標(biāo)為已讀,或者點(diǎn)擊組上面的圖標(biāo)把項(xiàng)目中 所有的 通知標(biāo)為已讀。 在每個(gè)對(duì)號(hào)圖標(biāo)旁邊都有一個(gè)靜音按鈕,你可以點(diǎn)一下,以后就不會(huì)收到它相關(guān)的通知。
所有這些工具對(duì)于處理大量通知非常有用。 很多 GitHub 資深用戶都關(guān)閉郵件通知,在這個(gè)頁面上處理他們所有的通知。
郵件通知是你處理 GitHub 通知的另一種方式。 如果你打開這個(gè)選項(xiàng),每當(dāng)有通知時(shí),你會(huì)收到一封郵件。 我們?cè)?Figure 6-13 和 Figure 6-34 看到了一些例子。 郵件也會(huì)被合適地按話題組織在一起,如果你使用一個(gè)具有會(huì)話功能的郵件客戶端那會(huì)很方便。
GitHub 在發(fā)送給你的郵件頭中附帶了很多元數(shù)據(jù),這對(duì)于設(shè)置過濾器和郵件規(guī)則非常有幫助。
舉個(gè)例子,我們來看一看在 Figure 6-34 中發(fā)給 Tony 的一封真實(shí)郵件的頭部,我們會(huì)看到下面這些:
To: tonychacon/fade fade@noreply.github.com
Message-ID: tonychacon/fade/pull/1@github.com
Subject: [fade] Wait longer to see the dimming effect better (#1)
X-GitHub-Recipient: tonychacon
List-ID: tonychacon/fade
List-Post 和 List-Unsubscribe 字段表示如果你的郵件客戶端能夠處理這些,那么你可以很容易地在列表中發(fā)貼或取消對(duì)這個(gè)相關(guān)帖子的訂閱。 那會(huì)很有效率,就像在頁面中點(diǎn)擊靜音按鈕或在問題/合并請(qǐng)求頁面點(diǎn)擊 “Unsubscribe” 一樣。
值得注意的是,如果你同時(shí)打開了郵件和網(wǎng)頁通知,那么當(dāng)你在郵件客戶端允許加載圖片的情況下閱讀郵件通知時(shí),對(duì)應(yīng)的網(wǎng)頁通知也將會(huì)同時(shí)被標(biāo)記為已讀。
如果你的版本庫中有一些特殊文件,GitHub 會(huì)提醒你。
第一個(gè)就是 README 文件,可以是幾乎任何 GitHub 可以識(shí)別的格式。 例如,它可以是 README ,README.md , README.asciidoc 。 如果 GitHub 在你的版本庫中找到 README 文件,會(huì)把它在項(xiàng)目的首頁渲染出來。
很多團(tuán)隊(duì)在這個(gè)文件里放版本庫或項(xiàng)目新人需要了解的所有相關(guān)的信息。 它一般包含這些內(nèi)容:
該項(xiàng)目的作用
如何配置與安裝
有關(guān)如何使用和運(yùn)行的例子
項(xiàng)目的許可證
因?yàn)?GitHub 會(huì)渲染這個(gè)文件,你可以在文件里植入圖片或鏈接讓它更容易理解。
另一個(gè) GitHub 可以識(shí)別的特殊文件是 CONTRIBUTING 。 如果你有一個(gè)任意擴(kuò)展名的 CONTRIBUTING 文件,當(dāng)有人開啟一個(gè)合并請(qǐng)求時(shí) GitHub 會(huì)顯示 Figure 6-42。
http://wiki.jikexueyuan.com/project/pro-git-two/images/127.png" alt="" />
Figure 6-42. 開啟合并請(qǐng)求時(shí)有 CONTRIBUTING 文件存在. 這個(gè)的作用就是你可以在這里指出對(duì)于你的項(xiàng)目開啟的合并請(qǐng)求你想要的/不想要的各種事情。 這樣別人在開啟合并請(qǐng)求之前可以讀到這些指導(dǎo)方針。
對(duì)于一個(gè)單個(gè)項(xiàng)目其實(shí)沒有很多管理事務(wù)要做,但也有幾點(diǎn)有趣的。
如果你想用 “master” 之外的分支作為你的默認(rèn)分支,其他人將默認(rèn)會(huì)在這個(gè)分支上開啟合并請(qǐng)求或進(jìn)行瀏覽,你可以在你版本庫的設(shè)置頁面的 "options" 標(biāo)簽下修改。
http://wiki.jikexueyuan.com/project/pro-git-two/images/128.png" alt="" />
Figure 6-43. 改變項(xiàng)目的默認(rèn)分支. 簡單地改變默認(rèn)分支下拉列表中的選項(xiàng),它就會(huì)作為所有主要操作的默認(rèn)分支,他人進(jìn)行克隆時(shí)該分支也將被默認(rèn)檢出。
如果你想把一個(gè)項(xiàng)目移交給 GitHub 中的另一個(gè)人或另一個(gè)組織,還是設(shè)置頁面的這個(gè) "options"標(biāo)簽下有一個(gè) “Transfer ownership” 選項(xiàng)可以用來干這個(gè)。
http://wiki.jikexueyuan.com/project/pro-git-two/images/129.png" alt="" />
Figure 6-44. 把項(xiàng)目移交給另一個(gè) GitHub 用戶或組織。 當(dāng)你正準(zhǔn)備放棄一個(gè)項(xiàng)目且正好有別人想要接手時(shí),或者你的項(xiàng)目壯大了想把它移到一個(gè)組織里時(shí),這就管用了。
這么做不僅會(huì)把版本庫連帶它所有的觀察和星標(biāo)數(shù)都移到另一個(gè)地方,它還會(huì)將你的 URL 重定向到新的位置。 它也重定向了來自 Git 的克隆和抓取,而不僅僅是網(wǎng)頁端請(qǐng)求。