GitHub 是最大的 Git 版本庫託管商,是成千上萬的開發者和項目可以合做進行的中心。 大部分 Git 版本庫都託管在 GitHub,不少開源項目使用 GitHub 實現 Git 託管、問題追蹤、代碼審查以及其它事情。 因此,儘管這不是 Git 開源項目的直接部分,但若是想要專業地使用 Git,你將不可避免地與 GitHub 打交道,因此這依然是一個絕好的學習機會。css
本章將討論如何高效地使用 GitHub。 咱們將學習如何註冊和管理帳戶、建立和使用 Git 版本庫、向已有項目貢獻的通用流程以及如何接受別人向你本身項目的貢獻、GitHub 的編程接口和不少可以讓這些操做更簡單的小提示。html
若是你對如何使用 GitHub 託管本身的項目,或者與已經託管在 GitHub 上面的項目進行合做沒有興趣,能夠直接跳到 Git 工具 這一章。java
你所須要作的第一件事是建立一個免費帳戶。 直接訪問 https://github.com,選擇一個未被佔用的用戶名,提供一個電子郵件地址和密碼,點擊寫着「Sign up for GitHub」的綠色大按鈕便可。git
Figure 6-1. GitHub 註冊表單。github
你將看到的下一個頁面是升級計劃的價格頁面,目前咱們能夠直接忽略這個頁面。 GitHub 會給你提供的郵件地址發送一封驗證郵件。 儘快到你的郵箱進行驗證,這是很是重要的(咱們會在後面瞭解到這點)。web
NOTE編程
GitHub 爲免費帳戶提供了完整功能,限制是你的項目都將被徹底公開(每一個人都具備讀權限)。 GitHub 的付費計劃可讓你擁有必定數目的私有項目,不過本書將不涉及這部份內容。json
點擊屏幕左上角的 Octocat 圖標,你未來到控制面板頁面。 如今,你已經作好了使用 GitHub 的準備工做。vim
如今,你徹底可使用 https://
協議,經過你剛剛建立的用戶名和密碼訪問 Git 版本庫。 可是,若是僅僅克隆公有項目,你甚至不須要註冊——剛剛咱們建立的帳戶是爲了之後 fork 其它項目,以及推送咱們本身的修改。api
若是你習慣使用 SSH 遠程,你須要配置一個公鑰。 (若是你沒有公鑰,參考 生成 SSH 公鑰。) 使用窗口右上角的連接打開你的帳戶設置:
Figure 6-2. 「Account settings」連接。
而後在左側選擇「SSH keys」部分。
Figure 6-3. 「SSH keys」連接。
在這個頁面點擊「Add an SSH key
」按鈕,給你的公鑰起一個名字,將你的~/.ssh/id_rsa.pub
(或者自定義的其它名字)公鑰文件的內容粘貼到文本區,而後點擊「Add key」。
NOTE
確保給你的 SSH 密鑰起一個可以記得住的名字。 你能夠爲每個密鑰起名字(例如,「個人筆記本電腦」或者「工做帳戶」等),以便之後須要吊銷密鑰時可以方便地區分。
下一步,若是願意的話,你能夠將生成的頭像換成你喜歡的圖片。 首先,來到「Profile」標籤頁(在「SSH Keys」標籤頁上方),點擊「Upload new picture」。
Figure 6-4. 「Profile」連接。
咱們選擇了本地磁盤上的一個 Git 圖標,上傳以後還能夠對其進行裁剪。
Figure 6-5. 裁剪頭像
如今,在網站任意有你參與的位置,人們均可以在你的用戶名旁邊看到你的頭像。
若是你已經把頭像上傳到了流行的 Gravatar 託管服務(Wordpress 帳戶常用),默認就會使用這個頭像,所以,你就不須要進行這一步驟了。
GitHub 使用用戶郵件地址區分 Git 提交。 若是你在本身的提交中使用了多個郵件地址,但願 GitHub 能夠正確地將它們鏈接起來,你須要在管理頁面的 Emails 部分添加你擁有的全部郵箱地址。
Figure 6-6. 添加郵件地址
在 Figure 6-6 中咱們能夠看到一些不一樣的狀態。 頂部的地址是經過驗證的,而且被設置爲主要地址,這意味着該地址會接收到全部的通知和回覆。 第二個地址是經過驗證的,若是願意的話,能夠將其設置爲主要地址。 最後一個地址是未經過驗證的,這意味着你不能將其設置爲主要地址。 當 GitHub 發現任意版本庫中的任意提交信息包含了這些地址,它就會將其連接到你的帳戶。
最後,爲了額外的安全性,你絕對應當設置兩步驗證,簡寫爲 「2FA」。 兩步驗證是一種用於下降因你的密碼被盜而帶來的帳戶風險的驗證機制,如今已經變得愈來愈流行。 開啓兩步驗證,GitHub 會要求你用兩種不一樣的驗證方法,這樣,即便其中一個被攻破,攻擊者也不能訪問你的帳戶。
你能夠在 Account settings 頁面的 Security 標籤頁中找到 Two-factor Authentication 設置。
Figure 6-7. Security 標籤頁中的 2FA
點擊「Set up two-factor authentication」按鈕,會跳轉到設置頁面。該頁面容許你選擇是要在登陸時使用手機 app 生成輔助碼(一種「基於時間的一次性密碼」),仍是要 GitHub 經過 SMS 發送輔助碼。
選擇合適的方法後,按照提示步驟設置 2FA,你的帳戶會變得更安全,每次登陸 GitHub 時都須要提供除密碼之外的輔助碼。
帳戶已經創建好了,如今咱們來了解一些能幫助你對現有的項目作出貢獻的知識。
若是你想要參與某個項目,可是並無推送權限,這時能夠對這個項目進行「派生」。 派生的意思是指,GitHub 將在你的空間中建立一個徹底屬於你的項目副本,且你對其具備推送權限。
NOTE
在之前,「fork」是一個貶義詞,指的是某我的使開源項目向不一樣的方向發展,或者建立一個競爭項目,使得原項目的貢獻者分裂。 在 GitHub,「fork」指的是你本身的空間中建立的項目副本,這個副本容許你以一種更開放的方式對其進行修改。
經過這種方式,項目的管理者再也不須要忙着把用戶添加到貢獻者列表並給予他們推送權限。 人們能夠派生這個項目,將修改推送到派生出的項目副本中,並經過建立合併請求(Pull Request)來讓他們的改動進入源版本庫,下文咱們會詳細說明。 建立了合併請求後,就會開啓一個可供審查代碼的板塊,項目的擁有者和貢獻者能夠在此討論相關修改,直到項目擁有者對其感到滿意,而且認爲這些修改能夠被合併到版本庫。
你能夠經過點擊項目頁面右上角的「Fork」按鈕,來派生這個項目。
Figure 6-8. 「Fork」按鈕
稍等片刻,你將被轉到新項目頁面,該項目包含可寫的代碼副本。
GitHub 設計了一個以合併請求爲中心的特殊合做流程。 它基於咱們在 Git 分支 的 特性分支 中提到的工做流程。 無論你是在一個緊密的團隊中使用單獨的版本庫,或者使用許多的「Fork」來爲一個由陌生人組成的國際企業或網絡作出貢獻,這種合做流程都能應付。
流程一般以下:
從 master
分支中建立一個新分支
提交一些修改來改進項目
將這個分支推送到 GitHub 上
建立一個合併請求
討論,根據實際狀況繼續修改
項目的擁有者合併或關閉你的合併請求
這基本和 集成管理者工做流 中的一體化管理流程差很少,可是團隊可使用 GitHub 提供的網頁工具替代電子郵件來交流和審查修改。
如今咱們來看一個使用這個流程的例子。
Tony 在找一些能在他的 Arduino 微控制器上運行的代碼,他以爲 https://github.com/schacon/blink中的代碼不錯。
Figure 6-9. 他想要作出貢獻的項目
可是有個問題,這個代碼中的的閃爍頻率過高,咱們以爲 3 秒一次比 1 秒一次更好一些。 因此讓咱們來改進這個程序,並將修改後的代碼提交給這個項目。
首先,單擊「Fork」按鈕來得到這個項目的副本。 咱們使用的用戶名是「tonychacon」,因此這個項目副本的訪問地址是: https://github.com/tonychacon/blink
。 咱們將它克隆到本地,建立一個分支,修改代碼,最後再將改動推送到 GitHub。
$ git clone https://github.com/tonychacon/blinkCloning into 'blink'... $ cd blink $ git checkout -b slow-blink
Switched to a new branch 'slow-blink' $ sed -i '' 's/1000/3000/' blink.ino
$ git diff --word-diff
diff --git a/blink.ino b/blink.ino index 15b9911..a6cc5a5 100644 --- a/blink.ino +++ b/blink.ino @@ -18,7 +18,7 @@ void setup() { // the loop routine runs over and over again forever: void loop() { digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) [-delay(1000);-]{+delay(3000);+} // wait for a second digitalWrite(led, LOW); // turn the LED off by making the voltage LOW [-delay(1000);-]{+delay(3000);+} // wait for a second } $ git commit -a -m 'three seconds is better'
[slow-blink 5ca509d] three seconds is better 1 file changed, 2 insertions(+), 2 deletions(-) $ git push origin slow-blink
Username for 'https://github.com': tonychacon Password for 'https://tonychacon@github.com': Counting objects: 5, done. Delta compression using up to 8 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 340 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) To https://github.com/tonychacon/blink * [new branch] slow-blink -> slow-blink
將派生出的副本克隆到本地
建立出名稱有意義的分支
修改代碼
檢查改動
將改動提交到分支中
將新分支推送到 GitHub 的副本中
如今到 GitHub 上查看以前的項目副本,能夠看到 GitHub 提示咱們有新的分支,而且顯示了一個大大的綠色按鈕讓咱們能夠檢查咱們的改動,並給源項目建立合併請求。
你也能夠到「Branches」(分支)頁面查看分支並建立合併請求: https://github.com/<用戶名>/<項目名>/branches
Figure 6-10. 合併請求按鈕
若是你點擊了那個綠色按鈕,就會看到一個新頁面,在這裏咱們能夠對改動填寫標題和描述,讓項目的擁有者考慮一下咱們的改動。一般花點時間來編寫個清晰有用的描述是個不錯的主意,這能讓做者明白爲何這個改動能夠給他的項目帶來好處,而且讓他接受合併請求。
同時咱們也能看到比主分支中所「領先」(ahead)的提交(在這個例子中只有一個)以及全部將會被合併的改動與以前代碼的對比。
Figure 6-11. 合併請求建立頁面
當你單擊了「Create pull request」(建立合併請求)的按鈕後,這個項目的擁有者將會收到一條包含關改動和合並請求頁面的連接的提醒。
NOTE
雖然合併請求一般是在貢獻者準備好在公開項目中提交改動的時候提交,可是也常被用在仍處於開發階段的內部項目中。由於合併請求在提交後 依然能夠加入新的改動 ,它也常常被用來創建團隊合做的環境,而不僅是在最終階段使用。
如今,項目的擁有者能夠看到你的改動併合並它,拒絕它或是發表評論。在這裏咱們就看成他喜歡這個點子,可是他想要讓燈熄滅的時間比點亮的時間稍長一些。
接下來可能會經過電子郵件進行互動,就像咱們在 分佈式 Git 中提到的工做流程那樣,可是在 GitHub,這些都在線上完成。項目的擁有者能夠審查修改,只須要單擊某一行,就能夠對其發表評論。
Figure 6-12. 對合並請求內的特定一行發表評論
當維護者發表評論後,提交合並請求的人,以及全部正在關注(Watching)這個版本庫的用戶都會收到通知。咱們待會兒將會告訴你如何修改這項設置。如今,若是 Tony 有開啓電子郵件提醒,他將會收到這樣的一封郵件:
Figure 6-13. 經過電子郵件發送的評論提醒
每一個人都能在合併請求中發表評論。在 Figure 6-14 裏咱們能夠看到項目擁有者對某行代碼發表評論,並在討論區留下了一個普通評論。你能夠看到被評論的代碼也會在互動中顯示出來。
Figure 6-14. 合併請求討論頁面
如今貢獻者能夠看到如何作才能讓他們的改動被接受。幸運的是,這也是一件輕鬆的事情。若是你使用的是電子郵件進行交流,你須要再次對代碼進行修改並從新提交至郵件列表,在 GitHub 上,你只須要再次提交到你的分支中並推送便可。
若是貢獻者完成了以上的操做,項目的擁有者會再次收到提醒,當他們查看頁面時,將會看到最新的改動。事實上,只要提交中有一行代碼改動,GitHub 都會注意到並處理掉舊的變動集。
Figure 6-15. 最終的合併請求
若是你點開合併請求的「Files Changed」(更改的文件)選項卡,你將會看到「整理過的」差別表 —— 也就是這個分支被合併到主分支以後將會產生的全部改動,其實就是 git diff master...<分支名>
命令的執行結果。你能夠瀏覽 肯定引入了哪些東西 來了解更多關於差別表的知識。
你還會注意到,GitHub 會檢查你的合併請求是否能直接合並,若是能夠,將會提供一個按鈕來進行合併操做。這個按鈕只在你對版本庫有寫入權限而且能夠進行簡潔合併時纔會顯示。你點擊後 GitHub 將作出一個「非快進式」(non-fast-forward)合併,即便這個合併 可以 快進式(fast-forward)合併,GitHub 依然會建立一個合併提交。
若是你須要,你還能夠將分支拉取並在本地合併。若是你將這個分支合併到 master
分支中並推送到 GitHub,這個合併請求會被自動關閉。
這就是大部分 GitHub 項目使用的工做流程。建立分支,基於分支建立合併請求,進行討論,根據須要繼續在分支上進行修改,最終關閉或合併合併請求。
NOTE
有件很重要的事情:你能夠在同一個版本庫中不一樣的分支提交合並請求。若是你正在和某人實現某個功能,並且你對項目有寫權限,你能夠推送分支到版本庫,並在 master
分支提交一個合併請求並在此進行代碼審查和討論的操做。不須要進行「Fork」。
目前,咱們學到了如何在 GitHub 平臺對一個項目進行最基礎的貢獻。如今咱們會教給你一些小技巧,讓你能夠更加有效率地使用合併請求。
有一件重要的事情:許多項目並不認爲合併請求能夠做爲補丁,就和經過郵件列表工做的的項目對補丁貢獻的見解同樣。大多數的 GitHub 項目將合併請求的分支看成對改動的交流方式,並將變動集合起來統一進行合併。
這是個重要的差別,由於通常來講改動會在代碼完成前提出,這和基於郵件列表的補丁貢獻有着天差地別。這使得維護者們能夠更早的溝通,由社區中的力量能提出更好的方案。當有人從合併請求提交了一些代碼,而且維護者和社區提出了一些意見,這個補丁系列並不須要從頭來過,只須要將改動從新提交併推送到分支中,這使得討論的背景和過程能夠齊頭並進。
舉個例子,你能夠回去看看 Figure 6-15,你會注意到貢獻者沒有變基他的提交再提交一個新的合併請求,而是直接增長了新的提交併推送到已有的分支中。若是你以後再回去查看這個合併請求,你能夠輕鬆地找到這個修改的緣由。點擊網頁上的「Merge」(合併)按鈕後,會創建一個合併提交併指向這個合併請求,你就能夠很輕鬆的研究原來的討論內容。
若是你的合併請求因爲過期或其餘緣由不能幹淨地合併,你須要進行修復才能讓維護者對其進行合併。GitHub 會對每一個提交進行測試,讓你知道你的合併請求可否簡潔的合併。
Figure 6-16. 不能進行乾淨合併
若是你看到了像 Figure 6-16 中的畫面,你就須要修復你的分支讓這個提示變成綠色,這樣維護者就不須要再作額外的工做。
你有兩種方法來解決這個問題。你能夠把你的分支變基到目標分支中去(一般是你派生出的版本庫中的master
分支),或者你能夠合併目標分支到你的分支中去。
GitHub 上的大多數的開發者會使用後一種方法,基於咱們在上一節提到的理由:咱們最看重的是歷史記錄和最後的合併,變基除了給你帶來看上去簡潔的歷史記錄,只會讓你的工做變得更加困難且更容易犯錯。
若是你想要合併目標分支來讓你的合併請求變得可合併,你須要將源版本庫添加爲一個新的遠端,並從遠端抓取內容,合併主分支的內容到你的分支中去,修復全部的問題並最終從新推送回你提交合並請求使用的分支。
在這個例子中,咱們再次使用以前的「tonychacon」用戶來進行示範,源做者提交了一個改動,使得合併請求和它產生了衝突。如今來看咱們解決這個問題的步驟。
$ git remote add upstream https://github.com/schacon/blink$ git fetch upstream
remote: Counting objects: 3, done. remote: Compressing objects: 100% (3/3), done. Unpacking objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0) From https://github.com/schacon/blink * [new branch] master -> upstream/master $ git merge upstream/master
Auto-merging blink.ino CONFLICT (content): Merge conflict in blink.ino Automatic merge failed; fix conflicts and then commit the result. $ vim blink.ino
$ git add blink.ino $ git commit [slow-blink 3c8d735] Merge remote-tracking branch 'upstream/master' \ into slower-blink $ git push origin slow-blink
Counting objects: 6, done. Delta compression using up to 8 threads. Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 682 bytes | 0 bytes/s, done. Total 6 (delta 2), reused 0 (delta 0) To https://github.com/tonychacon/blink ef4725c..3c8d735 slower-blink -> slow-blink
將源版本庫添加爲一個遠端,並命名爲「upstream」(上游)
從遠端抓取最新的內容
將主分支的內容合併到你的分支中
修復產生的衝突
再推送回同一個分支
你完成了上面的步驟後,合併請求將會自動更新並從新檢查是否能幹淨的合併。
Figure 6-17. 合併請求如今能夠乾淨地合併了
Git 的偉大之處就是你能夠一直重複以上操做。若是你有一個運行了十分久的項目,你能夠輕鬆地合併目標分支且只須要處理最近的一次衝突,這使得管理流程更加容易。
若是你必定想對分支作變基並進行清理,你能夠這麼作,可是強烈建議你不要強行的提交到已經提交了合併請求的分支。若是其餘人拉取了這個分支並進行一些修改,你將會遇到 變基的風險 中提到的問題。相對的,將變基後的分支推送到 GitHub 上的一個新分支中,而且建立一個全新的合併請求引用舊的合併請求,而後關閉舊的合併請求。
你的下個問題多是「我該如何引用舊的合併請求?」。有許多方法可讓你在 GitHub 上的幾乎任何地方引用其餘東西。
先從如何對合並請求或議題(Issue)進行相互引用開始。全部的合併請求和議題在項目中都會有一個獨一無二的編號。舉個例子,你沒法同時擁有 3 號合併請求和 3 號議題。若是你想要引用任何一個合併請求或議題,你只須要在提交或描述中輸入 #<編號>
便可。你也能夠指定引用其餘版本庫的議題或合併請求,若是你想要引用其餘人對該版本庫的「Fork」中的議題或合併請求,輸入 用戶名#<編號>
,若是在不一樣的版本庫中,輸入 用戶名/版本庫名#<編號>
。
咱們來看一個例子。假設咱們對上個例子中的分支進行了變基,併爲此建立一個新的合併請求,如今咱們但願能在新的合併請求中引用舊的合併請求。咱們同時但願引用一個派生出的項目中的議題和一個徹底不一樣的項目中的議題,就能夠像 Figure 6-18 這樣填寫描述。
Figure 6-18. 在合併請求中的交叉引用
當咱們提交了這個合併請求,咱們將會看到以上內容被渲染成這樣:Figure 6-19
Figure 6-19. 在合併請求中渲染後的交叉引用
你會注意到完整的 GitHub 地址被簡化了,只留下了必要的信息。
若是 Tony 回去關閉了源合併請求,咱們能夠看到一個被引用的提示,GitHub 會自動的反向追蹤事件並顯示在合併請求的時間軸上。這意味着任何查看這個合併請求的人能夠輕鬆地訪問新的合併請求。這個連接就像 Figure 6-20 中展現的那樣。
Figure 6-20. 在合併請求中渲染後的交叉引用
除了議題編號外,你還能夠經過使用提交的 SHA-1 來引用提交。你必須完整的寫出 40 位長的 SHA,GitHub 會在評論中自動地產生指向這個提交的連接。一樣的,你能夠像引用議題同樣對「Fork」出的項目中的提交或者其餘項目中的提交進行引用。
對於在 GitHub 中絕大多數文本框中可以作到的事,引用其餘議題只是個開始。在議題和合並請求的描述,評論和代碼評論還有其餘地方,均可以使用「GitHub 風格的 Markdown」。Markdown 可讓你輸入純文本,可是渲染出豐富的內容。
查看 Figure 6-21 裏的例子來了解如何書寫評論或文本,並經過 Markdown 進行渲染。
Figure 6-21. 一個 Markdown 的例子和渲染效果
GitHub 風格的 Markdown 增長了一些基礎的 Markdown 中作不到的東西。它在建立合併請求和議題中的評論和描述時十分有用。
第一個 GitHub 專屬的 Markdown 功能,特別是用在合併請求中,就是任務列表。一個任務列表能夠展現出一系列你想要完成的事情,並帶有複選框。把它們放在議題或合併請求中時,一般能夠展現你想要完成的事情。
你能夠這樣建立一個任務列表:
- [X] 編寫代碼 - [ ] 編寫全部測試程序 - [ ] 爲代碼編寫文檔
若是咱們將這個列表加入合併請求或議題的描述中,它將會被渲染 Figure 6-22 這樣。
Figure 6-22. Markdown 評論中渲染後的任務列表
在合併請求中,任務列表常常被用來在合併以前展現這個分支將要完成的事情。最酷的地方就是,你只須要點擊複選框,就能更新評論 —— 你不須要直接修改 Markdown。
不只如此,GitHub 還會將你在議題和合並請求中的任務列表整理起來集中展現。舉個例子,若是你在一個合併請求中有任務清單,你將會在全部合併請求的總覽頁面上看到它的進度。這使得人們能夠把一個合併請求分解成不一樣的小任務,同時便於其餘人瞭解分支的進度。你能夠在 Figure 6-23 看到一個例子。
Figure 6-23. 在合併請求列表中的任務列表總結
當你在實現一個任務的早期就提交合並請求,並使用任務清單追蹤你的進度,這個功能會十分的有用。
你也能夠在評論中摘錄代碼。這在你想要展現還沒有提交到分支中的代碼時會十分有用。它也常常被用在展現沒法正常工做的代碼或這個合併請求須要的代碼。
你須要用「反引號」將須要添加的摘錄代碼包起來。
```java for(int i=0 ; i < 5 ; i++) { System.out.println("i is : " + i); } ```
若是加入語言的名稱,就像咱們這裏加入的「java」同樣,GitHub 會自動嘗試對摘錄的片斷進行語法高亮。在下面的例子中,它最終會渲染成這個樣子: Figure 6-24 。
Figure 6-24. 渲染後的摘錄代碼示例
若是你在回覆一個很長的評論之中的一小段,你只須要複製你須要的片斷,並在每行前添加 >
符號便可。事實上,由於這個功能會被常常用到,它也有一個快捷鍵。只要你把你要回應的文字選中,並按下 r
鍵,選中的問題會自動引用並填入評論框。
引用的部分就像這樣:
> Whether 'tis Nobler in the mind to suffer > The Slings and Arrows of outrageous Fortune, How big are these slings and in particular, these arrows?
通過渲染後,就會變成這樣: Figure 6-25
Figure 6-25. 渲染後的引用示例
最後,咱們能夠在評論中使用表情符號。這常常出如今 GitHub 的議題和合並請求的評論中。GitHub 上甚至有表情助手。若是你在輸入評論時以 :
開頭,自動完成器會幫助你找到你須要的表情。
Figure 6-26. 表情符號自動完成器
你也能夠在評論的任何地方使用 :<表情名稱>:
來添加表情符號。舉個例子,你能夠輸入如下文字:
I :eyes: that :bug: and I :cold_sweat:. :trophy: for :microscope: it. :+1: and :sparkles: on this :ship:, it's :fire::poop:! :clap::tada::panda_face:
渲染以後,就會變成這樣: Figure 6-27
Figure 6-27. 使用了大量表情符號的評論
雖然這個功能並非很是實用,可是它在這種不方便表達感情的媒體裏,加入了趣味的元素。
NOTE
事實上如今已經有大量的在線服務可使用表情符號,這裏有個列表可讓你快速的找到能表達你的情緒的表情符號:
http://www.emoji-cheat-sheet.com
從技術層面來講,這並非 GitHub 風格 Markdown 的功能,可是也頗有用。若是不想使用 Markdown 語法來插入圖片,GitHub 容許你經過拖拽圖片到文本區來插入圖片。
Figure 6-28. 經過拖拽的方式自動插入圖片
若是你回去查看 Figure 6-18 ,你會發現文本區上有個「Parsed as Markdown」的提示。點擊它你能夠了解全部能在 GitHub 上使用的 Markdown 功能。
如今咱們能夠很方便地向一個項目貢獻內容,來看一下另外一個方面的內容:建立、維護和管理你本身的項目。
讓咱們建立一個版本庫來分享咱們的項目。 經過點擊面板右側的「New repository」按鈕,或者頂部工具條你用戶名旁邊的 +
按鈕來開始咱們的旅程。 參見 Figure 6-30。
Figure 6-29. 這是 「Your repositories」區域.
Figure 6-30. 這是 「New repository」 下拉列表.
這會帶你到 「new repository」 表單:
Figure 6-31. 這是 「new repository」 表單.
這裏除了一個你必需要填的項目名,其餘字段都是可選的。 如今只須要點擊 「Create Repository」 按鈕,Duang!!! – 你就在 GitHub 上擁有了一個以 <user>/<project_name>
命名的新倉庫了。
由於目前暫無代碼,GitHub 會顯示有關建立新版本庫或者關聯到一個已有的 Git 版本庫的一些說明。 咱們不會在這裏詳細說明此項,若是你須要複習,去看 Git 基礎。
如今你的項目就託管在 GitHub 上了,你能夠把 URL 給任何你想分享的人。 GitHub 上的項目可經過 HTTP 或 SSH 訪問,格式是:HTTP : https://github.com/<user>/<project_name>
, SSH :git@github.com:<user>/<project_name>
。 Git 能夠經過以上兩種 URL 進行抓取和推送,可是用戶的訪問權限又因鏈接時使用的證書不一樣而異。
NOTE
一般對於公開項目能夠優先分享基於 HTTP 的 URL,由於用戶克隆項目不須要有一個 GitHub 賬號。 若是你分享 SSH URL,用戶必須有一個賬號而且上傳 SSH 密鑰才能訪問你的項目。 HTTP URL 與你貼到瀏覽器裏查看項目用的地址是同樣的。
若是你想與他人合做,並想給他們提交的權限,你須要把他們添加爲 「Collaborators」。 若是 Ben,Jeff,Louise 都在 GitHub 上註冊了,你想給他們推送的權限,你能夠將他們添加到你的項目。 這樣作會給他們 「推送」 權限,就是說他們對項目和 Git 版本庫都有讀寫的權限。
點擊邊欄底部的 「Settings」 連接。
Figure 6-32. 版本庫設置連接.
而後從左側菜單中選擇 「Collaborators」 。 而後,在輸入框中填寫用戶名,點擊 「Add collaborator.」 若是你想受權給多我的,你能夠屢次重複這個步驟。 若是你想收回權限,點擊他們同一行右側的 「X」
Figure 6-33. 版本庫合做者.
如今你有一個包含一些代碼的項目,可能還有幾個有推送權限的合做者,下面來看當你收到合併請求時該作什麼。
合併請求能夠來自倉庫副本的一個分支,或者同一倉庫的另外一個分支。 惟一的區別是 fork 過來的一般是和你不能互相推送的人,而內部的推送一般均可以互相訪問。
做爲例子,假設你是 「tonychacon」 ,你建立了一個名爲 「fade」 的 Arduino 項目.
有人來修改了你的代碼,給你發了一個合併請求。 你會收一封關於合併請求的提醒郵件,它看起來像Figure 6-34。
Figure 6-34. 新的合併請求的郵件通知.
關於這個郵件有幾個要注意的地方。 它會給你一個小的變更統計結果 — 一個包含合併請求中改變的文件和改變了多少的列表。 它還給你一個 GitHub 上進行合併請求操做的連接。 還有幾個能夠在命令行使用的 URL。
若是你注意到 git pull <url> patch-1
這一行,這是一種合併遠程分支的簡單方式,無需必須添加一個遠程分支。 咱們很快會在 檢出遠程分支._ 講到它。 若是你願意,你能夠建立並切換到一個主題分支,而後運行這個命令把合併請求合併進來。
還有一些有趣的 URL,像 .diff
和 .patch
,就像你猜的那樣,它們提供 diff 和 patch 的標準版本。 你能夠技術性地用下面的方法合併「合併請求」:
$ curl http://github.com/tonychacon/fade/pull/1.patch | git am
就像咱們在 GitHub 流程,_ 說過的,如今你能夠跟開啓合併請求的人進行會話。 你既能夠對某些代碼添加註釋,也能夠對整個提交添加註釋或對整個合併請求添加註釋,在任何地方均可以用 GitHub Flavored Markdown。
每次有人在合併請求上進行註釋你都會收到通知郵件,通知你哪裏發生改變。 他們都會包含一個到改變位置的連接,你能夠直接在郵件中對合並請求進行註釋。
Figure 6-35. Responses to emails are included in the thread.
一旦代碼符合了你的要求,你想把它合併進來,你能夠把代碼拉取下來在本地進行合併,也能夠用咱們以前提到過的 git pull <url> <branch>
語法,或者把 fork 添加爲一個 remote,而後進行抓取和合並。
對於很瑣碎的合併,你也能夠用 GitHub 網站上的 「Merge」 按鈕。 它會作一個 「non-fast-forward」 合併,即便能夠快進(fast-forward)合併也會產生一個合併提交記錄。 就是說不管如何,只要你點擊 merge 按鈕,就會產生一個合併提交記錄。 你能夠在 Figure 6-36 看到,若是你點擊提示連接,GitHub 會給你全部的這些信息。
Figure 6-36. 合併按鈕和手工合併一個合併請求的指令.
若是你決定不合並它,你能夠把合併請求關掉,開啓合併請求的人會收到通知。
若是你正在處理 許多 合併請求,不想添加一堆 remote 或者每次都要作一次拉取,這裏有一個能夠在 GitHub 上用的小技巧。 這是有點高級的技巧,但它至關有用,咱們會在 引用規格 有更多的細節說明。
實際上 GitHub 在服務器上把合併請求分支視爲一種 「假分支」。 默認狀況下你克隆時不會獲得它們,但它們仍是隱式地存在,你能夠很容易地訪問到它們。
爲了展現這個,咱們要用到一個叫作 ls-remote
的低級命令(一般被叫作「plumbing」,咱們會在 底層命令和高層命令 讀到更多相關內容)。 這個命令在平常 Git 操做中基本不會用到,但在顯示服務器上有哪些引用(reference)時很管用。
若是在咱們以前用過的 「blink」 版本庫上使用這個命令,咱們會獲得一個版本庫裏全部的分支,標籤和其它引用(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
固然,若是你在你本身的版本庫或其它你想檢查的遠程版本庫中使用 git ls-remote origin
,它會顯示類似的內容。
若是版本庫在 GitHub 上而且有打開的合併請求,你會獲得一些以 refs/pull/
開頭的引用。 它們其實是分支,但由於它們不在 refs/heads/
中,因此正常狀況下你克隆時不會從服務器上獲得它們 — 抓取過程正常狀況下會忽略它們。
每一個合併請求有兩個引用 - 其中以 /head
結尾的引用指向的提交記錄與合併請求分支中的最後一個提交記錄是同一個。 因此若是有人在咱們的版本庫中開啓了一個合併請求,他們的分支叫作 bug-fix
,指向a5a775
這個提交記錄,那麼在 咱們的 版本庫中咱們沒有 bug-fix
分支(由於那是在他們的 fork 中),但咱們 能夠 有一個 pull/<pr#>/head
指向 a5a775
。 這意味着咱們能夠很容易地拉取每個合併請求分支而不用添加一堆 remote。
如今,你能夠像直接抓取引用同樣抓取那些分支或提交。
$ git fetch origin refs/pull/958/head From https://github.com/libgit2/libgit2 * branch refs/pull/958/head -> FETCH_HEAD
這告訴 Git: 「鏈接到 origin
這個 remote,下載名字爲 refs/pull/958/head
的引用。」 Git 高高興興去執行,下載構建那個引用須要的全部內容,而後把指針指向 .git/FETCH_HEAD
下面你想要的提交記錄。 而後你能夠用 git merge FETCH_HEAD
把它合併到你想進行測試的分支,但那個合併的提交信息看起來有點怪。 然而,若是你須要審查 一大批 合併請求,這樣操做會很麻煩。
還有一種方法能夠抓取 全部的 合併請求,而且在你鏈接到遠程(remote)的時候保持更新。 用你最喜歡的編輯器打開 .git/config
,查找 origin
遠程(remote)。 看起來差很少像下面這樣:
[remote "origin"] url = https://github.com/libgit2/libgit2 fetch = +refs/heads/*:refs/remotes/origin/*
以 fetch =
開頭的行是一個 「refspec.」 它是一種把 remote 的名稱映射到你本地 .git
目錄的方法。 這一條(就是上面的這一條)告訴 Git,「remote 上 refs/heads
下面的內容在我本地版本庫中都放在 refs/remotes/origin
。」 你能夠把這一段修改一下,添加另外一個 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
的引用應該在本地版本庫像refs/remotes/origin/pr/123
同樣存儲」 如今,若是你保存那個文件,執行 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 # …
如今全部的合併請求在本地像分支同樣展示,它們是隻讀的,當你執行抓取時它們也會更新。 這讓在本地測試合併請求中的代碼變得超級簡單:
$ 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'
你的鷹眼系統會發如今 refspec 的 remote 部分的結尾有個 head
。 在 GitHub 那邊也有一個refs/pull/#/merge
引用,它表明的是若是你在網站上按了 「merge」 按鈕對應的提交記錄。 這甚至讓你能夠在按按鈕以前就測試這個合併。
你不只能夠在主分支或者說 master
分支上開啓合併請求,實際上你能夠在網絡上的任何一個分支上開啓合併請求。 其實,你甚至能夠在另外一個合併請求上開啓一個合併請求。
若是你看到一個合併請求在向正確的方向發展,而後你想在這個合併請求上作一些修改或者你不太肯定這是個好主意,或者你沒有目標分支的推送權限,你能夠直接在合併請求上開啓一個合併請求。
當你開啓一個合併請求時,在頁面的頂端有一個框框顯示你要合併到哪一個分支和你從哪一個分支合併過來的。 若是你點擊那個框框右邊的 「Edit」 按鈕,你不只能夠改變分支,還能夠選擇哪一個 fork。
Figure 6-37. 手工修改合併請求的目標.
這裏你能夠很簡單地指明合併你的分支到哪個合併請求或 fork。
GitHub 內置了一個很好的通知系統,當你須要與別人或別的團隊交流時用起來很方便。
在任何評論中你能夠先輸入一個@
,系統會自動補全項目中合做者或貢獻者的名字和用戶名。
Figure 6-38. 輸入 @ 來提醒某人.
你也能夠提醒不在列表中的用戶,可是一般自動補全用起更快。
當你發佈了一個帶用戶提醒的評論,那個用戶會收到通知。 這意味着把人們拉進會話中要比讓他們投票有效率得多。 對於 GitHub 上的合併請求,人們常常把他們團隊或公司中的其它人拉來審查問題或合併請求。
若是有人收到了合併請求或問題的提醒,他們會"訂閱"它,後面有新的活動發生他們都會持續收到提醒。 若是你是合併請求或者問題的發起方你也會被訂閱上,好比你在關注一個版本庫或者你評論了什麼東西。 若是你不想再收到提醒,在頁面上有個 「Unsubscribe」 按鈕,點一下就不會再收到更新了。
Figure 6-39. 取消訂閱一個問題或合併請求.
當咱們在這提到特指 GitHub 的 「notifications」 ,指的是當 GitHub 上有事件發生時,它通知你的方式,這裏有幾種不一樣的方式來配置它們。 若是你打開配置頁面的 「Notification center」 標籤,你能夠看到一些選項。
Figure 6-40. 通知中心選項.
有兩個選項,經過"郵件(Email)"和經過"網頁(Web)",你能夠選用一個或者都不選或者都選。
網頁通知只在 GitHub 上存在,你也只能在 GitHub 上查看。 若是你打開了這個選項而且有一個你的通知,你會在你屏幕上方的通知圖標上看到一個小藍點。參見 Figure 6-41。
Figure 6-41. 通知中心.
若是你點擊那個玩意兒,你會看到你被通知到的全部條目,按照項目分好了組。 你能夠點擊左邊欄的項目名字來過濾項目相關的通知。 你能夠點擊通知旁邊的對號圖標把通知標爲已讀,或者點擊組上面的圖標把項目中 全部的 通知標爲已讀。 在每一個對號圖標旁邊都有一個靜音按鈕,你能夠點一下,之後就不會收到它相關的通知。
全部這些工具對於處理大量通知很是有用。 不少 GitHub 資深用戶都關閉郵件通知,在這個頁面上處理他們全部的通知。
郵件通知是你處理 GitHub 通知的另外一種方式。 若是你打開這個選項,每當有通知時,你會收到一封郵件。 咱們在 Figure 6-13 和 Figure 6-34 看到了一些例子。 郵件也會被合適地按話題組織在一塊兒,若是你使用一個具備會話功能的郵件客戶端那會很方便。
GitHub 在發送給你的郵件頭中附帶了不少元數據,這對於設置過濾器和郵件規則很是有幫助。
舉個例子,咱們來看一看在 Figure 6-34 中發給 Tony 的一封真實郵件的頭部,咱們會看到下面這些:
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 <fade.tonychacon.github.com> List-Archive: https://github.com/tonychacon/fade List-Post: <mailto:reply+i-4XXX@reply.github.com> List-Unsubscribe: <mailto:unsub+i-XXX@reply.github.com>,... X-GitHub-Recipient-Address: tchacon@example.com
這裏有一些有趣的東西。 若是你想高亮或者轉發這個項目甚至這個合併請求相關的郵件,Message-ID
中的信息會以 <user>/<project>/<type>/<id>
的格式展示全部的數據。 例如,若是這是一個問題(issue),那麼 <type>
字段就會是 「issues」 而不是 「pull」 。
List-Post
和 List-Unsubscribe
字段表示若是你的郵件客戶端可以處理這些,那麼你能夠很容易地在列表中發貼或取消對這個相關帖子的訂閱。 那會頗有效率,就像在頁面中點擊靜音按鈕或在問題/合併請求頁面點擊 「Unsubscribe」 同樣。
值得注意的是,若是你同時打開了郵件和網頁通知,那麼當你在郵件客戶端容許加載圖片的狀況下閱讀郵件通知時,對應的網頁通知也將會同時被標記爲已讀。
若是你的版本庫中有一些特殊文件,GitHub 會提醒你。
第一個就是 README
文件,能夠是幾乎任何 GitHub 能夠識別的格式。 例如,它能夠是 README
,README.md
, README.asciidoc
。 若是 GitHub 在你的版本庫中找到 README 文件,會把它在項目的首頁渲染出來。
不少團隊在這個文件裏放版本庫或項目新人須要瞭解的全部相關的信息。 它通常包含這些內容:
該項目的做用
如何配置與安裝
有關如何使用和運行的例子
項目的許可證
如何向項目貢獻力量
由於 GitHub 會渲染這個文件,你能夠在文件裏植入圖片或連接讓它更容易理解。
另外一個 GitHub 能夠識別的特殊文件是 CONTRIBUTING
。 若是你有一個任意擴展名的 CONTRIBUTING
文件,當有人開啓一個合併請求時 GitHub 會顯示 Figure 6-42。
Figure 6-42. 開啓合併請求時有 CONTRIBUTING 文件存在.
這個的做用就是你能夠在這裏指出對於你的項目開啓的合併請求你想要的/不想要的各類事情。 這樣別人在開啓合併請求以前能夠讀到這些指導方針。
對於一個單個項目其實沒有不少管理事務要作,但也有幾點有趣的。
若是你想用 「master」 以外的分支做爲你的默認分支,其餘人將默認會在這個分支上開啓合併請求或進行瀏覽,你能夠在你版本庫的設置頁面的 "options" 標籤下修改。
Figure 6-43. 改變項目的默認分支.
簡單地改變默認分支下拉列表中的選項,它就會做爲全部主要操做的默認分支,他人進行克隆時該分支也將被默認檢出。
若是你想把一個項目移交給 GitHub 中的另外一我的或另外一個組織,仍是設置頁面的這個 "options"標籤下有一個 「Transfer ownership」 選項能夠用來幹這個。
Figure 6-44. 把項目移交給另外一個 GitHub 用戶或組織。
當你正準備放棄一個項目且正好有別人想要接手時,或者你的項目壯大了想把它移到一個組織裏時,這就管用了。
這麼作不只會把版本庫連帶它全部的觀察和星標數都移到另外一個地方,它還會將你的 URL 重定向到新的位置。 它也重定向了來自 Git 的克隆和抓取,而不只僅是網頁端請求。
除了我的賬戶以外,GitHub 還提供被稱爲組織(Organizations)的賬戶。 組織帳戶和我的帳戶同樣都有一個用於存放所擁有項目的命名空間,可是許多其餘的東西都是不一樣的。 組織賬戶表明了一組共同擁有多個項目的人,同時也提供一些工具用於對成員進行分組管理。 一般,這種帳戶被用於開源羣組(例如:「perl」或者「rails」),或者公司(例如:「google」或者「twitter」)。
咱們能夠很簡單地建立一個組織,只須要點擊任意 GitHub 頁面右上角的「+」圖標,在菜單中選擇「New organization」便可。
Figure 6-45. 「New organization」菜單項
首先你必須提供組織的名稱和組織的主要聯繫郵箱。 而後,若是你但願的話,也能夠邀請其餘用戶做爲共同擁有人。
完成以上步驟後,你就會擁有一個全新的組織。 相似於我的賬戶,若是組織的全部內容都是開源的,那麼你就能夠無償使用這個組織。
做爲一個組織的擁有者,當你在派生一個版本庫的時候,你能夠選擇把它派生到你的組織的命名空間內。 當你新建版本庫時,你能夠把它存放到你的我的賬戶或你擁有的組織內。 同時,你也會自動地「關注」全部這些組織內的新版本庫。
就像頭像,你能夠爲你的組織上傳頭像,使它更個性化。 同時,也和我的賬戶相似,組織會有一個着陸頁(landing page),用於列出該組織全部的版本庫,而且該頁面可供全部人瀏覽。
下面咱們來講一些組織和我的賬戶不一樣的地方。
組織使用團隊(Teams)來管理成員,團隊就是組織中的一組我的帳戶和版本庫,以及團隊成員對這些版本庫的訪問權限。
例如,假設你的公司有三個版本庫:frontend
、backend
和 deployscripts
。 你會但願你的 HTML/CSS/Javascript 開發者有 frontend
或者 backend
的訪問權限,操做人員有 backend
和deployscripts
的訪問權限。 團隊讓這個任務變得更簡單,而不用爲每一個版本庫管理它的協做者。
組織頁面主要由一個面板(dashboard)構成,這個儀表盤包含了這個組織內的全部版本庫,用戶和團隊。
Figure 6-46. 組織頁面
你能夠點擊 Figure 6-46 右邊的團隊側邊欄(Teams)來管理你的團隊。 點擊以後,你會進入一個新頁面,在這裏你能夠添加新成員和版本庫到團隊中,或者管理團隊的訪問權限和其它設置。 每一個團隊對於版本庫能夠有隻讀、讀寫和管理三種權限。 你能夠經過點擊在 Figure 6-47 內的 「Settings」 按鈕更改相應權限等級。
Figure 6-47. 團隊頁面
當你邀請一個用戶加入團隊,該用戶會收到一封通知他被邀請的郵件。
除此以外,團隊也相似於我的賬戶,有 @mentions
(例如:@acmecorp/frontend
)的功能,不一樣之處就在於被說起的團隊內全部成員都會成爲這個話題的訂閱者。 當你但願獲得團隊中某我的的關注,又不知道具體應該問誰的時候,這個功能就顯得頗有幫助。
一個用戶能夠加入任意數量的團隊,因此別把本身侷限於擁有訪問控制的團隊。 對於某一類課題,像 ux
,css
或者 refactoring
這樣有着特殊關注點的團隊就顯得頗有幫助,而像 legal
和 colorblind
這樣的就徹底是針對它們各自領域的。
組織的擁有者還能夠訪問組織中發生的事情的全部信息。 在 Audit Log 標籤頁有整個組織的日誌,你能夠看到誰在世界上哪一個地方作了什麼事。
Figure 6-48. 審計日誌
你也能夠經過選定某一類型的事件、某個地方、某我的對日誌進行過濾。
因此如今咱們已經介紹了 GitHub 的大部分功能與工做流程,可是任意一個小組或項目都會去自定義,由於他們想要創造或擴展想要整合的服務。
對咱們來講很幸運的是,GitHub 在許多方面都真的很方便 Hack。 在本節中咱們將會介紹如何使用 GitHub 鉤子系統與 API 接口,使 GitHub 按照咱們的設想來工做。
GitHub 倉庫管理中的鉤子與服務區塊是 GitHub 與外部系統交互最簡單的方式。
首先咱們來看一下服務。 鉤子與服務整合均可以在倉庫的設置區塊中找到,就在咱們以前添加協做者與改變項目的默認分支的地方。 在 「Webhooks and Services」 標籤下你會看到與 Figure 6-49 相似的內容。
Figure 6-49. 服務與鉤子配置區域
有許多能夠選擇的服務,大多數是整合到其餘的商業與開源系統中。 它們中的大多數是爲了整合持續集成服務、BUG 與問題追蹤系統、聊天室系統與文檔系統。 咱們將會經過設置一個很是簡單的例子來介紹。 若是從 「Add Service」 選擇 「email」,會獲得一個相似 Figure 6-50 的配置屏幕。
Figure 6-50. 電子郵件服務配置
在本例中,若是咱們點擊 「Add service」 按鈕,每次有人推送內容到倉庫時,指定的電子郵件地址都會收到一封郵件。 服務能夠監聽許多不一樣類型的事件,可是大多數只監聽推送事件而後使用那些數據作一些事情。
若是有一個正在使用的系統想要整合到 GitHub,應當先檢查這裏看有沒有已有的可用的服務整合。 例如,若是正使用 Jenkins 來測試你的代碼庫,當每次有人推送到你的倉庫時你能夠啓用 Jenkins 內置的整合啓動測試運行。
若是須要作一些更具體的事,或者想要整合一個不在這個列表中的服務或站點,能夠轉而使用更通用的鉤子系統。 GitHub 倉庫鉤子是很是簡單的。 指定一個 URL 而後 GitHub 在任一指望的事件發生時就會發送一個 HTTP 請求到那個 URL 。
一般作這件事的方式是能夠設置一個小的 web 服務來監聽 GitHub 鉤子請求而後使用收到的數據作一些事情。
爲了啓用一個鉤子,點擊 Figure 6-49 中的 「Add webhook」 按鈕。 這會將你引導至一個相似Figure 6-51 的頁面。
Figure 6-51. Web 鉤子配置
Web 鉤子的設置很是簡單。 大多數狀況下只須要輸入一個 URL 與一個密鑰而後點擊 「Add webhook」。 有幾個選項能夠指定在哪一個事件時想要 GitHub 發送請求 — 默認的行爲是隻有當某人推送新代碼到倉庫的任一分支時的 push
事件得到一個請求。
讓咱們看一個設置處理 web 鉤子的 web 服務的小例子。 咱們將會使用 Ruby web 框架 Sinatra,由於它至關簡潔,應該可以輕鬆地看到咱們正在作什麼。
假設咱們想要在某個特定的人推送到咱們的項目的特定分支並修改一個特定文件時獲得一封郵件。 咱們能夠至關容易地使用相似下面的代碼作到:
require 'sinatra' require 'json' require 'mail' post '/payload' do push = JSON.parse(request.body.read) # parse the JSON # gather the data we're looking for pusher = push["pusher"]["name"] branch = push["ref"] # get a list of all the files touched files = push["commits"].map do |commit| commit['added'] + commit['modified'] + commit['removed'] end files = files.flatten.uniq # check for our criteria if pusher == 'schacon' && branch == 'ref/heads/special-branch' && files.include?('special-file.txt') Mail.deliver do from 'tchacon@example.com' to 'tchacon@example.com' subject 'Scott Changed the File' body "ALARM" end end end
這裏咱們拿到一個 GitHub 傳送給咱們的 JSON 請求而後查找推送者,他們推送到了什麼分支以及推送的全部提交都改動了哪些文件。 而後咱們檢查它是否與咱們的條件區配,若是匹配則發送一封郵件。
爲了開發與測試相似這樣的東西,在設置鉤子的地方有一個漂亮的開發者控制檯。 能夠看到 GitHub 爲那個 webhook 的最後幾回請求。 對每個鉤子,當它發送後均可以深刻挖掘,檢測它是不是成功的與請求及迴應的消息頭與消息體。 這使得測試與調試鉤子很是容易。
Figure 6-52. Web 鉤子調試信息
開發者控制檯的另外一個很棒的功能是能夠輕鬆地從新發送任何請求來測試你的服務。
關於如何編寫 web 鉤子與全部可監聽的不一樣事件類型的更多信息,請訪問在https://developer.github.com/webhooks/ 的 GitHub 開發者文檔。
服務與鉤子給你提供了一種方式來接收關於在倉庫中發生的事件的推送通知,可是如何獲取相關事件的詳情呢?如何自動化一些諸如添加協做者或給問題加標籤的事情呢?
這是 GitHub API 派上用場的地方。 在自動化流行的趨勢下,GitHub 提供了大量的 API 接口,能夠進行幾乎任何能在網站上進行的操做。 在本節中咱們將會學習如何受權與鏈接到 API,如何經過 API 在一個問題上評論與如何修改一個 Pull Request 的狀態。
能夠作的最基本的事情是向一個不須要受權的接口上發送一個簡單的 GET 請求。 該接口多是一個用戶或開源項目的只讀信息。 例如,若是咱們想要知道更多關於名爲 「schacon」 的用戶信息,咱們能夠運行相似下面的東西:
$ curl https://api.github.com/users/schacon { "login": "schacon", "id": 70, "avatar_url": "https://avatars.githubusercontent.com/u/70", # … "name": "Scott Chacon", "company": "GitHub", "following": 19, "created_at": "2008-01-27T17:19:28Z", "updated_at": "2014-06-10T02:37:23Z" }
有大量相似這樣的接口來得到關於組織、項目、問題、提交的信息 — 差很少就是你能在 GitHub 上看到的全部東西。 甚至可使用 API 來渲染任意 Markdown 或尋找一個 .gitignore
模板。
$ curl https://api.github.com/gitignore/templates/Java { "name": "Java", "source": "*.class # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.jar *.war *.ear # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* " }
然而,若是想要在網站上進行一個操做,如在 Issue 或 Pull Request 上評論,或者想要查看私有內容或與其交互,你須要受權。
這裏提供了幾種受權方式。 你可使用僅需用戶名與密碼的基本受權,可是一般更好的主意是使用一個我的訪問令牌。 能夠從設置頁的 「Applications」 標籤生成訪問令牌。
Figure 6-53. 從設置頁的 「Applications」 標籤生成訪問令牌。
它會詢問這個令牌的做用域與一個描述。 確保使用一個好的描述信息,這樣當腳本或應用再也不使用時你會很放心地移除。
GitHub 只會顯示令牌一次,因此記得必定要拷貝它。 如今能夠在腳本中使用它代替使用用戶名寫密碼來受權。 這很漂亮,由於能夠限制想要作的範圍而且令牌是可廢除的。
這也會有一個提升頻率上限的附加優勢。 若是沒有受權的話,你會被限制在一小時最多發起 60 次請求。 若是受權則能夠一小時最多發起 5000 次請求。
因此讓咱們利用它來對咱們的其中一個問題進行評論。 想要對一個特定問題 Issue #6 留下一條評論。 必須使用剛剛生成的令牌做爲 Authorization 頭信息,發送一個到repos/<user>/<repo>/issues/<num>/comments
的 HTTP POST 請求。
$ curl -H "Content-Type: application/json" \ -H "Authorization: token TOKEN" \ --data '{"body":"A new comment, :+1:"}' \ https://api.github.com/repos/schacon/blink/issues/6/comments { "id": 58322100, "html_url": "https://github.com/schacon/blink/issues/6#issuecomment-58322100", ... "user": { "login": "tonychacon", "id": 7874698, "avatar_url": "https://avatars.githubusercontent.com/u/7874698?v=2", "type": "User", }, "created_at": "2014-10-08T07:48:19Z", "updated_at": "2014-10-08T07:48:19Z", "body": "A new comment, :+1:" }
如今若是進入到那個問題,能夠看到咱們剛剛發佈的評論,像 Figure 6-54 同樣。
Figure 6-54. 從 GitHub API 發佈的一條評論
可使用 API 去作任何能夠在網站上作的事情 — 建立與設置里程碑、指派人員到 Issues 與 Pull Requests,建立與修改標籤、訪問提交數據、建立新的提交與分支、打開關閉或合併 Pull Requests、建立與編輯團隊、在 Pull Request 中評論某行代碼、搜索網站等等。
若是使用 Pull Requests 的話咱們將要看到的最後一個例子會頗有用。 每個提交能夠有一個或多個與它關聯的狀態,有 API 來添加與查詢狀態。
大多數持續集成與測試服務經過測試推送的代碼後使用這個 API 來回應,而後報告提交是否經過了所有測試。 你也可使用該接口來檢查提交信息是否通過合適的格式化、提交者是否遵循了全部你的貢獻準則、提交是否通過有效的簽名 — 種種這類事情。
假設在倉庫中設置了一個 web 鉤子訪問一個用來檢查提交信息中的 Signed-off-by
字符串的小的 web 服務。
require 'httparty' require 'sinatra' require 'json' post '/payload' do push = JSON.parse(request.body.read) # parse the JSON repo_name = push['repository']['full_name'] # look through each commit message push["commits"].each do |commit| # look for a Signed-off-by string if /Signed-off-by/.match commit['message'] state = 'success' description = 'Successfully signed off!' else state = 'failure' description = 'No signoff found.' end # post status to GitHub sha = commit["id"] status_url = "https://api.github.com/repos/#{repo_name}/statuses/#{sha}" status = { "state" => state, "description" => description, "target_url" => "http://example.com/how-to-signoff", "context" => "validate/signoff" } HTTParty.post(status_url, :body => status.to_json, :headers => { 'Content-Type' => 'application/json', 'User-Agent' => 'tonychacon/signoff', 'Authorization' => "token #{ENV['TOKEN']}" } ) end end
但願這至關容易作。 在這個 web 鉤子處理器中咱們瀏覽剛剛推送上來的每個提交,在提交信息中查找字符串 Signed-off-by 而且最終使用 HTTP 向 /repos/<user>/<repo>/statuses/<commit_sha>
API 接口發送一個帶有狀態的 POST 請求。
在本例中能夠發送一個狀態(success, failure, error)、一個發生了什麼的描述信息、一個用戶能夠了解更多信息的目標 URL 與一個 「context」 以防一個單獨的提交有多個狀態。 例如,一個測試服務能夠提供一個狀態與一個相似這樣的驗證服務也可能提供一個狀態 — 「context」 字段是用來區別它們的。
若是某人在 GitHub 中打開了一個新的 Pull Request 而且這個鉤子已經設置,會看到相似 Figure 6-55的信息。
Figure 6-55. 經過 API 的提交狀態
如今能夠看到一個小的綠色對勾標記在提交信息中有 「Signed-off-by」 的提交旁邊,紅色的對勾標記在做者忘記簽名的提交旁邊。 也能夠看到 Pull Request 顯示在那個分支上的最後提交的狀態,若是失敗的話會警告你。 若是對測試結果使用這個 API 那麼就不會不當心合併某些未經過測試的最新提交。
儘管咱們在這些例子中都是經過 curl
與基本的 HTTP 請求來作幾乎全部的事情,還有一些以更天然的方式利用 API 的開源庫存在着。 在寫這篇文章的時候,被支持的語言包括 Go、Objective-C、Ruby 與 .NET。 訪問 http://github.com/octokit 瞭解更多相關信息,它們幫你處理了更多 HTTP 相關的內容。
但願這些工具能幫助你自定義與修改 GitHub 來更好地爲特定的工做流程工做。 關於所有 API 的完整文檔與常見任務的指南,請查閱 https://developer.github.com。