Git用户手册--GitHub

6.1 GitHub - 帐户的建立和配置

 

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

GitHub 注册表单。Figure 6-1. GitHub 注册表单。github

你将看到的下一个页面是升级计划的价格页面,目前咱们能够直接忽略这个页面。 GitHub 会给你提供的邮件地址发送一封验证邮件。 尽快到你的邮箱进行验证,这是很是重要的(咱们会在后面了解到这点)。web

NOTE编程

GitHub 为免费帐户提供了完整功能,限制是你的项目都将被彻底公开(每一个人都具备读权限)。 GitHub 的付费计划可让你拥有必定数目的私有项目,不过本书将不涉及这部份内容。json

点击屏幕左上角的 Octocat 图标,你未来到控制面板页面。 如今,你已经作好了使用 GitHub 的准备工做。vim

SSH 访问

如今,你彻底可使用 https:// 协议,经过你刚刚建立的用户名和密码访问 Git 版本库。 可是,若是仅仅克隆公有项目,你甚至不须要注册——刚刚咱们建立的帐户是为了之后 fork 其它项目,以及推送咱们本身的修改。api

若是你习惯使用 SSH 远程,你须要配置一个公钥。 (若是你没有公钥,参考 生成 SSH 公钥。) 使用窗口右上角的连接打开你的帐户设置:

``Account settings''连接。Figure 6-2. “Account settings”连接。

而后在左侧选择“SSH keys”部分。

``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”。

``Profile''连接。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 设置。

Security 标签页中的 2FAFigure 6-7. Security 标签页中的 2FA

点击“Set up two-factor authentication”按钮,会跳转到设置页面。该页面容许你选择是要在登陆时使用手机 app 生成辅助码(一种“基于时间的一次性密码”),仍是要 GitHub 经过 SMS 发送辅助码。

选择合适的方法后,按照提示步骤设置 2FA,你的帐户会变得更安全,每次登陆 GitHub 时都须要提供除密码之外的辅助码。

 

6.2 GitHub - 对项目作出贡献

 

对项目作出贡献

帐户已经创建好了,如今咱们来了解一些能帮助你对现有的项目作出贡献的知识。

派生(Fork)项目

若是你想要参与某个项目,可是并无推送权限,这时能够对这个项目进行“派生”。 派生的意思是指,GitHub 将在你的空间中建立一个彻底属于你的项目副本,且你对其具备推送权限。

NOTE

在之前,“fork”是一个贬义词,指的是某我的使开源项目向不一样的方向发展,或者建立一个竞争项目,使得原项目的贡献者分裂。 在 GitHub,“fork”指的是你本身的空间中建立的项目副本,这个副本容许你以一种更开放的方式对其进行修改。

经过这种方式,项目的管理者再也不须要忙着把用户添加到贡献者列表并给予他们推送权限。 人们能够派生这个项目,将修改推送到派生出的项目副本中,并经过建立合并请求(Pull Request)来让他们的改动进入源版本库,下文咱们会详细说明。 建立了合并请求后,就会开启一个可供审查代码的板块,项目的拥有者和贡献者能够在此讨论相关修改,直到项目拥有者对其感到满意,而且认为这些修改能够被合并到版本库。

你能够经过点击项目页面右上角的“Fork”按钮,来派生这个项目。

“Fork”按钮.Figure 6-8. “Fork”按钮

稍等片刻,你将被转到新项目页面,该项目包含可写的代码副本。

GitHub 流程

GitHub 设计了一个以合并请求为中心的特殊合做流程。 它基于咱们在 Git 分支 的 特性分支 中提到的工做流程。 无论你是在一个紧密的团队中使用单独的版本库,或者使用许多的“Fork”来为一个由陌生人组成的国际企业或网络作出贡献,这种合做流程都能应付。

流程一般以下:

  1. 从 master 分支中建立一个新分支

  2. 提交一些修改来改进项目

  3. 将这个分支推送到 GitHub 上

  4. 建立一个合并请求

  5. 讨论,根据实际状况继续修改

  6. 项目的拥有者合并或关闭你的合并请求

这基本和 集成管理者工做流 中的一体化管理流程差很少,可是团队可使用 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/blink 1
Cloning into 'blink'...

$ cd blink
$ git checkout -b slow-blink 2
Switched to a new branch 'slow-blink'

$ sed -i '' 's/1000/3000/' blink.ino 3

$ git diff --word-diff 4
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' 5
[slow-blink 5ca509d] three seconds is better
 1 file changed, 2 insertions(+), 2 deletions(-)

$ git push origin slow-blink 6
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

1

将派生出的副本克隆到本地

2

建立出名称有意义的分支

3

修改代码

4

检查改动

5

将改动提交到分支中

6

将新分支推送到 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

没必要老是 Fork

有件很重要的事情:你能够在同一个版本库中不一样的分支提交合并请求。若是你正在和某人实现某个功能,并且你对项目有写权限,你能够推送分支到版本库,并在 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 1

$ git fetch upstream 2
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 3
Auto-merging blink.ino
CONFLICT (content): Merge conflict in blink.ino
Automatic merge failed; fix conflicts and then commit the result.

$ vim blink.ino 4
$ git add blink.ino
$ git commit
[slow-blink 3c8d735] Merge remote-tracking branch 'upstream/master' \
    into slower-blink

$ git push origin slow-blink 5
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

1

将源版本库添加为一个远端,并命名为“upstream”(上游)

2

从远端抓取最新的内容

3

将主分支的内容合并到你的分支中

4

修复产生的冲突

5

再推送回同一个分支

你完成了上面的步骤后,合并请求将会自动更新并从新检查是否能干净的合并。

修复了的合并请求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”出的项目中的提交或者其余项目中的提交进行引用。

Markdown

对于在 GitHub 中绝大多数文本框中可以作到的事,引用其余议题只是个开始。在议题和合并请求的描述,评论和代码评论还有其余地方,均可以使用“GitHub 风格的 Markdown”。Markdown 可让你输入纯文本,可是渲染出丰富的内容。

查看 Figure 6-21 里的例子来了解如何书写评论或文本,并经过 Markdown 进行渲染。

Markdown 例子Figure 6-21. 一个 Markdown 的例子和渲染效果

GitHub 风格的 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. 渲染后的引用示例

表情符号(Emoji)

最后,咱们能够在评论中使用表情符号。这常常出如今 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

EmojiFigure 6-27. 使用了大量表情符号的评论

虽然这个功能并非很是实用,可是它在这种不方便表达感情的媒体里,加入了趣味的元素。

NOTE

事实上如今已经有大量的在线服务可使用表情符号,这里有个列表可让你快速的找到能表达你的情绪的表情符号:

http://www.emoji-cheat-sheet.com

图片

从技术层面来讲,这并非 GitHub 风格 Markdown 的功能,可是也颇有用。若是不想使用 Markdown 语法来插入图片,GitHub 容许你经过拖拽图片到文本区来插入图片。

拖拽插入图片Figure 6-28. 经过拖拽的方式自动插入图片

若是你回去查看 Figure 6-18 ,你会发现文本区上有个“Parsed as Markdown”的提示。点击它你能够了解全部能在 GitHub 上使用的 Markdown 功能。

6.3 GitHub - 维护项目

 

维护项目

如今咱们能够很方便地向一个项目贡献内容,来看一下另外一个方面的内容:建立、维护和管理你本身的项目。

建立新的版本库

让咱们建立一个版本库来分享咱们的项目。 经过点击面板右侧的“New repository”按钮,或者顶部工具条你用户名旁边的 + 按钮来开始咱们的旅程。 参见 Figure 6-30

``Your repositories'' 区域.Figure 6-29. 这是 “Your repositories”区域.``new repository'' 下拉列表.Figure 6-30. 这是 “New repository” 下拉列表.

这会带你到 “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

第一个就是 README 文件,能够是几乎任何 GitHub 能够识别的格式。 例如,它能够是 READMEREADME.md , README.asciidoc 。 若是 GitHub 在你的版本库中找到 README 文件,会把它在项目的首页渲染出来。

不少团队在这个文件里放版本库或项目新人须要了解的全部相关的信息。 它通常包含这些内容:

  • 该项目的做用

  • 如何配置与安装

  • 有关如何使用和运行的例子

  • 项目的许可证

  • 如何向项目贡献力量

由于 GitHub 会渲染这个文件,你能够在文件里植入图片或连接让它更容易理解。

贡献 CONTRIBUTING

另外一个 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 的克隆和抓取,而不只仅是网页端请求。

6.4 GitHub - 管理组织

 

管理组织

除了我的账户以外,GitHub 还提供被称为组织(Organizations)的账户。 组织帐户和我的帐户同样都有一个用于存放所拥有项目的命名空间,可是许多其余的东西都是不一样的。 组织账户表明了一组共同拥有多个项目的人,同时也提供一些工具用于对成员进行分组管理。 一般,这种帐户被用于开源群组(例如:“perl”或者“rails”),或者公司(例如:“google”或者“twitter”)。

组织的基本知识

咱们能够很简单地建立一个组织,只须要点击任意 GitHub 页面右上角的“+”图标,在菜单中选择“New organization”便可。

``New organization''菜单项Figure 6-45. “New organization”菜单项

首先你必须提供组织的名称和组织的主要联系邮箱。 而后,若是你但愿的话,也能够邀请其余用户做为共同拥有人。

完成以上步骤后,你就会拥有一个全新的组织。 相似于我的账户,若是组织的全部内容都是开源的,那么你就能够无偿使用这个组织。

做为一个组织的拥有者,当你在派生一个版本库的时候,你能够选择把它派生到你的组织的命名空间内。 当你新建版本库时,你能够把它存放到你的我的账户或你拥有的组织内。 同时,你也会自动地“关注”全部这些组织内的新版本库。

就像头像,你能够为你的组织上传头像,使它更个性化。 同时,也和我的账户相似,组织会有一个着陆页(landing page),用于列出该组织全部的版本库,而且该页面可供全部人浏览。

下面咱们来讲一些组织和我的账户不一样的地方。

团队

组织使用团队(Teams)来管理成员,团队就是组织中的一组我的帐户和版本库,以及团队成员对这些版本库的访问权限。

例如,假设你的公司有三个版本库:frontendbackend 和 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 标签页有整个组织的日志,你能够看到谁在世界上哪一个地方作了什么事。

orgs 03 auditFigure 6-48. 审计日志

你也能够经过选定某一类型的事件、某个地方、某我的对日志进行过滤。

6.5 GitHub - 脚本 GitHub

 

脚本 GitHub

因此如今咱们已经介绍了 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 的页面。

Web 钩子配置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 的最后几回请求。 对每个钩子,当它发送后均可以深刻挖掘,检测它是不是成功的与请求及回应的消息头与消息体。 这使得测试与调试钩子很是容易。

Web 钩子调试信息Figure 6-52. Web 钩子调试信息

开发者控制台的另外一个很棒的功能是能够轻松地从新发送任何请求来测试你的服务。

关于如何编写 web 钩子与全部可监听的不一样事件类型的更多信息,请访问在https://developer.github.com/webhooks/ 的 GitHub 开发者文档。

GitHub API

服务与钩子给你提供了一种方式来接收关于在仓库中发生的事件的推送通知,可是如何获取相关事件的详情呢?如何自动化一些诸如添加协做者或给问题加标签的事情呢?

这是 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 同样。

API 评论Figure 6-54. 从 GitHub API 发布的一条评论

可使用 API 去作任何能够在网站上作的事情 — 建立与设置里程碑、指派人员到 Issues 与 Pull Requests,建立与修改标签、访问提交数据、建立新的提交与分支、打开关闭或合并 Pull Requests、建立与编辑团队、在 Pull Request 中评论某行代码、搜索网站等等。

修改 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 那么就不会不当心合并某些未经过测试的最新提交。

Octokit

尽管咱们在这些例子中都是经过 curl 与基本的 HTTP 请求来作几乎全部的事情,还有一些以更天然的方式利用 API 的开源库存在着。 在写这篇文章的时候,被支持的语言包括 Go、Objective-C、Ruby 与 .NET。 访问 http://github.com/octokit 了解更多相关信息,它们帮你处理了更多 HTTP 相关的内容。

但愿这些工具能帮助你自定义与修改 GitHub 来更好地为特定的工做流程工做。 关于所有 API 的完整文档与常见任务的指南,请查阅 https://developer.github.com

相关文章
相关标签/搜索