# GitHub

GitHub 是最大的 Git 版本库托管商,是成千上万的开发者和项目能够合作进行的中心,很多开源项目使用 GitHub 实现 Git 托管、问题追踪、代码审查以及其它事情。

在 GitHub 上克隆公有项目,你甚至不需要注册,不过为了以后 fork 其它项目,以及推送我们自己的修改。

现在,直接访问 https://github.com (opens new window),选择一个未被占用的用户名,提供一个电子邮件地址和密码后进行注册。

# 使用 SSH

创建账号后,你完全可以使用 https:// 协议,通过你刚刚创建的用户名和密码访问 Git 版本库,或者你也可以使用 SSH 远程。

你需要确认自己是否已经拥有密钥。默认情况下,用户的 SSH 密钥存储在其 ~/.ssh 目录下:

ls -al ~/.ssh

如果您没有现有的公钥和私钥对,或者不想使用任何可用于连接到 GitHub 的密钥对,则生成新的 SSH 密钥。

# 创建以所提供的电子邮件地址为标签的新 SSH 密钥
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

执行后会询问密钥的存储位置(默认是 .ssh/id_rsa),然后它会要求你输入两次密钥口令。如果你不想在使用密钥时输入口令,则将其留空。

完成后我们需要在密钥的存储位置中寻找一对以 id_rsa 命名的文件,其中一个带有 .pub 扩展名。.pub 文件是你的公钥,另一个则是与之对应的私钥。

要配置 GitHub 帐户使用新的(或现有)SSH 密钥,您还需要将其添加到 GitHub 帐户。首先,将 SSH 密钥复制到剪贴板:

pbcopy < ~/.ssh/id_rsa.pub

随后在 GitHub 任何页面的右上角,单击个人头像,再单击 Settings(设置),在打开的用户设置侧边栏中,单击 SSH and GPG keys(SSH 和 GPG 密钥)。

在这个页面点击“Add an SSH key”按钮,给你的公钥起一个名字,将复制的公钥文件的内容粘贴到文本区,最后点击“Add key”。

# 对项目做出贡献

如果你想要参与某个项目,但是并没有推送权限,这时可以对这个项目进行“派生(Fork)”。当你“派生”一个项目时,GitHub 会在你的空间中创建一个完全属于你的项目副本,且你对其具有推送权限。

整体流程包括:

  1. 派生一个项目;
  2. master 分支创建一个新分支;
  3. 在新分支上提交一些修改来改进项目;
  4. 将这个分支推送到 GitHub 上;
  5. 创建一个拉取请求;
  6. 讨论,根据实际情况继续修改;
  7. 项目的拥有者合并或关闭你的拉取请求;
  8. 将更新后的 master 分支同步到你的派生中。

在第 4 步完成后,再到 GitHub 上查看之前的项目副本,可以看到 GitHub 提示我们有新的分支,并且显示了一个大大的绿色按钮让我们可以检查我们的改动,并给源项目创建拉取请求。

如果我们点击那个绿色按钮,就会跳到一个新页面,在这里我们可以为拉取请求填写标题和描述。主要目的是让原项目拥有者明白你做了什么,为什么这个改动是正确的,以及接受此更改是否能够改进他的项目。

当你单击了“Create pull request”(创建拉取请求)的按钮后,这个项目的拥有者将会收到一条包含关改动和拉取请求页面的链接的提醒。

后续每个人都能在拉取请求中发表评论,根据讨论贡献者可以看到如何做才能让他们的改动被接受。对现有的拉取请求添加提交并不会触发提醒,修正后需要通过评论告知项目拥有者他完成了修改请求。

完成最后的修改并提交后,如果你对版本库有写入权限并且可以进行简洁合并时会显示合并按钮,点击后 GitHub 将做出一个“非快进式”合并,即使这个合并能够快进式合并,GitHub 依然会创建一个合并提交。

如果你需要,你还可以将分支拉取并在本地合并。如果你将这个分支合并到 master 分支中并推送到 GitHub,这个拉取请求会被自动关闭。

# 进阶

将拉取请求制作成补丁:

许多项目并不认为拉取请求可以作为补丁,而是将拉取请求的分支当作对改动的交流方式,并将变更集合起来统一进行合并。

例如,在提交代码之后,根据讨论会持续的修改代码并再次提交,在这个过程中贡献者没有变基他的提交再提交一个新的拉取请求,而是直接增加了新的提交并推送到已有的分支中。

如果你之后再回去查看这个拉取请求,你可以轻松地找到这个修改的原因。点击网页上的“Merge”(合并)按钮后,会建立一个合并提交并指向这个拉取请求。

与上游保持同步:

GitHub 会对每个提交进行测试,让你知道你的拉取请求能否简洁的合并。如果你的拉取请求由于过时或其他原因不能干净地合并,你需要进行修复才能让维护者对其进行合并。

你有两种方法来解决这个问题。你可以把你的分支变基到目标分支中去(通常是你派生出的版本库中的 master 分支),或者你可以合并目标分支到你的分支中去。

# 引用

有许多方法可以让你在 GitHub 上的几乎任何地方引用其他东西,比如引用旧的拉取请求。

所有的拉取请求和议题在项目中都会有一个独一无二的编号。举个例子,你无法同时拥有 3 号拉取请求和 3 号议题。如果你想要引用任何一个拉取请求或议题,你只需要在提交或描述中输入 #<编号> 即可。

你也可以指定引用其他版本库的议题或拉取请求,如果你想要引用其他人对该版本库的“Fork”中的议题或拉取请求,输入 用户名#<编号>,如果在不同的版本库中,输入 用户名/版本库名#<编号>

除了议题编号外,你还可以通过使用提交的 SHA-1 来引用提交。你必须完整的写出 40 位长的 SHA-1,GitHub 会在评论中自动地产生指向这个提交的链接。

同样的,你可以像引用议题一样对派生的项目中的提交或者其他项目中的提交进行引用。

另外,在任何评论中你可以先输入一个 @,系统会自动补全项目中合作者或贡献者的名字和用户名。当你发布了一个带用户提醒的评论,那个用户将会收到通知。

# 让派生仓库保持更新

当你派生了一个 GitHub 仓库之后,你的仓库(即你的“派生”)会独立于原仓库而独立。特别地,当原仓库有新的提交时,GitHub 不会自动更新,而是通知你当前的分支已经落后。

当你需要更新到最新时只需要:

git checkout master # 保证在 master 分支
git pull <origin_remote> # 拉取源仓库最新更改并合并到当前分支
git push origin master # 推送到远程的派生仓库

由于派生仓库 master 分支的远程更改来源通常都来自源仓库,所以我们可以进行如下设置:

git remote add <remote_name> <origin_remote> # 添加源仓库并取一个名字
git branch --set-upstream-to=<remote_name>/master master # 将 master 分支设置为从源仓库抓取
git config --local remote.pushDefault origin # 将默认推送仓库设置为 origin(派生仓库)

设置之后,后续再进行更新的流程将会变得很简单:

git checkout master
git pull
git push

# 维护项目

如果需要创建新的版本库,你可以通过点击页面右上角面板的 “New repository” 选项,除了必须要填的项目名,其他字段都是可选的。

每个项目应该有一个 README 文件,如果 GitHub 在你的版本库中找到 README 文件,会把它在项目的首页渲染出来。它主要用于:

  • 介绍该项目的作用;
  • 如何配置、安装和使用;
  • 有关如何使用和运行的例子;
  • 项目的许可证;
  • 如何向项目贡献力量。

如果你有一个任意扩展名的 CONTRIBUTING 文件,当有人开启一个合并请求时 GitHub 会显示 开启合并请求时有 CONTRIBUTING 文件存在。

对于某个项目,当你想与他人合作,并想给他们提交的权限时,你需要在项目配置下拉菜单中把他们添加为 “Collaborators”,如此他们对项目和 Git 版本库也将具备读写的权限。

当有人来修改了你的代码,给你发了一个合并请求后,你可以通过合并按钮合并该次请求,或者你也可以拉取拉取请求的分支到本地进行合并。

# 参考