Git
章节 ▾ 第 2 版

6.3 GitHub - 项目维护

维护项目

现在我们已经熟悉了如何为项目做贡献,让我们来看看另一面:创建、维护和管理你自己的项目。

创建新的仓库

让我们创建一个新的仓库来共享我们的项目代码。首先,点击仪表板右侧的“新建仓库”按钮,或者从用户名旁边的顶部工具栏中的“+”按钮,如 “新建仓库”下拉菜单 所示。

The “Your repositories” area
图 109.“你的仓库”区域
The “New repository” dropdown
图 110.“新建仓库”下拉菜单

这将带你到“新建仓库”表单

The “new repository” form
图 111.“新建仓库”表单

在这里,你只需要提供一个项目名称;其余字段都是可选的。现在,只需点击“创建仓库”按钮,然后,你就拥有了一个新的 GitHub 仓库,名为 <user>/<project_name>

由于你还没有代码,GitHub 会显示创建全新 Git 仓库或连接现有 Git 项目的说明。我们不会在这里详细说明;如果你需要复习,请查看 Git 基础

现在你的项目已托管在 GitHub 上,你可以将 URL 提供给任何你想要与之共享项目的人。GitHub 上的每个项目都可以通过 HTTPS 访问,例如 https://github.com/<user>/<project_name>,以及通过 SSH 访问,例如 [email protected]:<user>/<project_name>。Git 可以从这两个 URL 中获取和推送数据,但它们是根据连接到它们的用户的凭据进行访问控制的。

注意

对于公共项目,通常最好共享基于 HTTPS 的 URL,因为用户无需拥有 GitHub 账户即可克隆它。如果你提供 SSH URL,用户必须拥有账户和上传的 SSH 密钥才能访问你的项目。HTTPS URL 也是他们在浏览器中粘贴以查看该项目的完全相同的 URL。

添加协作者

如果你与其他人合作,并且希望授予他们提交权限,则需要将其添加为“协作者”。如果 Ben、Jeff 和 Louise 都在 GitHub 上注册了账户,并且你想授予他们对你的仓库的推送权限,则可以将其添加到你的项目中。这样做将授予他们“推送”权限,这意味着他们对项目和 Git 仓库都具有读写权限。

点击右侧边栏底部的“设置”链接。

The repository settings link
图 112. 仓库设置链接

然后从左侧菜单中选择“合作者”。然后,只需在框中输入用户名,然后单击“添加合作者”。您可以根据需要重复此操作,以授予您喜欢的任何人的访问权限。如果需要撤销访问权限,只需单击其行右侧的“X”。

The repository collaborators box
图 113. 仓库合作者框

管理拉取请求

现在您已经有了一个包含一些代码的项目,甚至可能有一些也具有推送访问权限的合作者,让我们来看一下当您自己收到拉取请求时该怎么做。

拉取请求可以来自您仓库的 fork 中的分支,也可以来自同一仓库中的另一个分支。唯一的区别在于,fork 中的拉取请求通常来自您无法推送其分支且他们也无法推送您的分支的人员,而对于内部拉取请求,通常双方都可以访问该分支。

对于这些示例,假设您是“tonychacon”,并且您创建了一个名为“fade”的新 Arduino 代码项目。

电子邮件通知

有人对您的代码进行了更改并向您发送了拉取请求。您应该会收到一封电子邮件,通知您新的拉取请求,它应该看起来像新的拉取请求的电子邮件通知

Email notification of a new Pull Request
图 114. 新的拉取请求的电子邮件通知

关于这封电子邮件,需要注意一些事项。它将为您提供一个小的 diffstat——一个已在拉取请求中更改的文件列表以及更改量。它为您提供了 GitHub 上拉取请求的链接。它还为您提供了一些可从命令行使用的 URL。

如果您注意到显示 git pull <url> patch-1 的行,这是一种在无需添加远程的情况下合并远程分支的简单方法。我们在检出远程分支中快速介绍了这一点。如果需要,您可以创建一个主题分支并切换到该分支,然后运行此命令以合并拉取请求更改。

其他有趣的 URL 是 .diff.patch URL,正如您可能猜到的那样,它们提供了拉取请求的统一 diff 和补丁版本。您可以在技术上使用类似以下内容合并拉取请求工作

$ curl https://github.com/tonychacon/fade/pull/1.patch | git am

在拉取请求上进行协作

正如我们在GitHub 工作流中所介绍的那样,您现在可以与打开拉取请求的人进行对话。您可以评论代码的特定行、评论整个提交或评论整个拉取请求本身,在任何地方使用 GitHub Flavored Markdown。

每当其他人对拉取请求发表评论时,您将继续收到电子邮件通知,以便您知道正在发生活动。每个通知都将包含一个指向拉取请求的链接,该链接指示活动发生的位置,您还可以直接回复电子邮件以评论拉取请求线程。

Responses to emails are included in the thread
图 115. 对电子邮件的回复包含在线程中

一旦代码处于您喜欢并希望将其合并的状态,您可以将代码拉取下来并在本地合并,可以使用我们之前看到的 git pull <url> <branch> 语法,也可以通过添加 fork 作为远程并获取和合并来实现。

如果合并很简单,您也可以直接点击 GitHub 网站上的“合并”按钮。这将执行“非快进”合并,即使可以执行快进合并,也会创建合并提交。这意味着无论如何,每次点击合并按钮时,都会创建一个合并提交。如合并按钮和手动合并拉取请求的说明所示,如果您点击提示链接,GitHub 会为您提供所有这些信息。

Merge button and instructions for merging a Pull Request manually
图 116. 合并按钮和手动合并拉取请求的说明

如果您决定不想合并它,您也可以关闭拉取请求,并通知打开它的人。

拉取请求引用

如果您要处理**大量**拉取请求,并且不想添加一堆远程或每次都执行一次性拉取,那么 GitHub 允许您使用一个巧妙的技巧。这有点高级技巧,我们将在Refspec中更详细地介绍此技巧,但它非常有用。

GitHub 实际上将仓库的拉取请求分支宣传为服务器上的某种伪分支。默认情况下,克隆时不会获取它们,但它们以一种隐藏的方式存在,您可以非常轻松地访问它们。

为了演示这一点,我们将使用一个低级命令(通常称为“管道”命令,我们将在管道和瓷器中了解更多信息)称为 ls-remote。此命令通常不用于日常 Git 操作,但它有助于向我们显示服务器上存在哪些引用。

如果我们针对之前使用的“blink”仓库运行此命令,我们将获得仓库中所有分支、标签和其他引用的列表。

$ 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 中),但我们将拥有指向 a5a775pull/<pr#>/head。这意味着我们可以非常轻松地一次性拉取所有拉取请求分支,而无需添加一堆远程。

现在,您可以执行类似于直接获取引用的操作。

$ git fetch origin refs/pull/958/head
From https://github.com/libgit2/libgit2
 * branch            refs/pull/958/head -> FETCH_HEAD

这告诉 Git:“连接到 origin 远程,并下载名为 refs/pull/958/head 的引用。”Git 乐于服从,并下载构建该引用所需的所有内容,并在 .git/FETCH_HEAD 下放置一个指向您想要的提交的指针。您可以继续使用 git merge FETCH_HEAD 将其合并到您要测试的分支中,但该合并提交消息看起来有点奇怪。此外,如果您要查看**大量**拉取请求,这会变得很繁琐。

还有一种方法可以获取所有拉取请求,并在每次连接到远程时保持它们更新。在您喜欢的编辑器中打开 .git/config,然后查找 origin 远程。它应该看起来有点像这样

[remote "origin"]
    url = https://github.com/libgit2/libgit2
    fetch = +refs/heads/*:refs/remotes/origin/*

fetch = 开头的行是“refspec”。它是一种将远程上的名称与本地 .git 目录中的名称映射起来的方法。此特定方法告诉 Git:“远程上位于 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 远程部分末尾的 head。GitHub 方面还有一个 refs/pull/#/merge 引用,它表示如果您点击网站上的“合并”按钮将产生的提交。这可以让您在点击按钮之前测试合并。

拉取请求上的拉取请求

您不仅可以打开针对主分支或 master 分支的拉取请求,还可以实际打开针对网络中任何分支的拉取请求。事实上,您甚至可以针对另一个拉取请求。

如果您看到一个正在朝正确方向发展的拉取请求,并且您有一个依赖于它的更改想法,或者您不确定它是否是一个好主意,或者您只是没有目标分支的推送访问权限,您可以直接向其打开一个拉取请求。

当您要打开拉取请求时,页面顶部有一个框,指定您请求拉取到的分支和请求拉取自的分支。如果您点击该框右侧的“编辑”按钮,则不仅可以更改分支,还可以更改 fork。

Manually change the Pull Request target fork and branch
图 117. 手动更改拉取请求目标 fork 和分支

在这里,您可以非常轻松地指定将您的新分支合并到另一个拉取请求或项目的另一个 fork 中。

提及和通知

GitHub 还内置了一个非常好的通知系统,当您有问题或需要特定个人或团队的反馈时,它会派上用场。

在任何评论中,您都可以开始键入 @ 字符,它将开始自动完成项目中合作者或贡献者的姓名和用户名。

Start typing @ to mention someone
图 118. 开始键入 @ 以提及某人

您还可以提及该下拉列表中不存在的用户,但自动完成器通常可以使其更快。

发布包含用户提及的评论后,该用户将收到通知。这意味着这可能是将人们拉入对话的一种非常有效的方法,而不是让他们轮询。在 GitHub 上的拉取请求中,人们经常会将团队或公司中的其他人拉进来审查问题或拉取请求。

如果有人在拉取请求或问题中被提及,他们将“订阅”它,并在其上发生任何活动时继续接收通知。如果您打开了某项内容、正在监视仓库或对某项内容发表了评论,您也将订阅该内容。如果您不再希望接收通知,则可以在页面上单击“取消订阅”按钮以停止接收更新。

Unsubscribe from an Issue or Pull Request
图 119. 取消订阅问题或拉取请求

通知页面

当我们在这里谈论关于 GitHub 的“通知”时,我们的意思是 GitHub 在事件发生时尝试与您联系的一种特定方式,并且您可以配置它们的一些不同方法。如果您从设置页面转到“通知中心”选项卡,您可以查看您拥有的某些选项。

Notification center options
图 120. 通知中心选项

这两个选择是通过“电子邮件”和“网络”获取通知,并且您可以选择在积极参与某些活动以及在您正在监视的仓库上的活动时选择其中一个、两者都不选或两者都选。

网络通知

网页通知仅存在于 GitHub 上,您只能在 GitHub 上查看它们。如果您在偏好设置中选择了此选项,并且触发了针对您的通知,您将在屏幕顶部的通知图标上看到一个小蓝点,如通知中心所示。

Notification center
图 121. 通知中心

如果您点击它,您将看到一个列表,其中包含所有您已收到通知的项目,按项目分组。您可以通过点击左侧边栏中的项目名称来筛选特定项目的通知。您还可以通过点击任何通知旁边的复选标记图标来确认通知,或者通过点击组顶部的复选标记来确认项目中的所有通知。在每个复选标记旁边还有一个静音按钮,您可以点击它以不再接收该项目的任何进一步通知。

所有这些工具对于处理大量通知都非常有用。许多 GitHub 高级用户会完全关闭电子邮件通知,并通过此屏幕管理所有通知。

电子邮件通知

电子邮件通知是您通过 GitHub 处理通知的另一种方式。如果您启用了此功能,您将收到每个通知的电子邮件。我们在作为电子邮件通知发送的评论新的 Pull Request 的电子邮件通知中看到了此功能的示例。电子邮件也将正确地进行线程化,如果您使用的是线程化电子邮件客户端,这将非常有用。

GitHub 发送给您的电子邮件标题中还嵌入了相当数量的元数据,这对于设置自定义过滤器和规则非常有用。

例如,如果我们查看新的 Pull Request 的电子邮件通知中显示的电子邮件中发送的实际电子邮件标题,我们将在发送的信息中看到以下内容

To: tonychacon/fade <[email protected]>
Message-ID: <tonychacon/fade/pull/[email protected]>
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:[email protected]>
List-Unsubscribe: <mailto:[email protected]>,...
X-GitHub-Recipient-Address: [email protected]

这里有一些有趣的事情。如果您想突出显示或重新路由到此特定项目甚至 Pull Request 的电子邮件,Message-ID 中的信息将以<user>/<project>/<type>/<id>格式提供所有数据。例如,如果这是一个问题,则<type>字段将是“issues”,而不是“pull”。

List-PostList-Unsubscribe 字段意味着,如果您拥有一个理解这些字段的邮件客户端,您可以轻松地发布到列表或从线程中“取消订阅”。这基本上等同于点击通知网页版本上的“静音”按钮或 Issue 或 Pull Request 页面本身上的“取消订阅”。

还值得注意的是,如果您同时启用了电子邮件和网页通知,并且您阅读了通知的电子邮件版本,如果您的邮件客户端允许显示图片,则网页版本也将被标记为已读。

特殊文件

如果您的存储库中存在一些特殊文件,GitHub 会注意到它们。

README

第一个是README文件,它可以是 GitHub 识别为散文格式的几乎任何格式。例如,它可以是READMEREADME.mdREADME.asciidoc等。如果 GitHub 在您的源代码中看到README文件,它将在项目的登录页面上渲染它。

许多团队使用此文件来保存与项目相关的所有信息,供可能不熟悉存储库或项目的人员使用。这通常包括以下内容:

  • 项目的用途

  • 如何配置和安装它

  • 如何使用它或使其运行的示例

  • 项目提供的许可证

  • 如何为它做贡献

由于 GitHub 将渲染此文件,因此您可以在其中嵌入图像或链接,以方便理解。

CONTRIBUTING

GitHub 识别的另一个特殊文件是CONTRIBUTING文件。如果您有一个名为CONTRIBUTING且具有任何文件扩展名的文件,则当任何人开始打开 Pull Request 时,GitHub 将显示存在 CONTRIBUTING 文件时打开 Pull Request

Opening a Pull Request when a CONTRIBUTING file exists
图 122. 存在 CONTRIBUTING 文件时打开 Pull Request

这里的想法是,您可以在发送到项目的 Pull Request 中指定您想要或不想要的内容。这样,人们在打开 Pull Request 之前可能会实际阅读指南。

项目管理

通常,您对单个项目可以执行的管理操作不多,但有一些项目可能您感兴趣。

更改默认分支

如果您使用“master”以外的分支作为默认分支,并且希望人们在该分支上打开 Pull Request 或默认查看该分支,则可以在存储库的设置页面“选项”选项卡中更改它。

Change the default branch for a project
图 123. 更改项目的默认分支

只需在下拉列表中更改默认分支,这将成为从那时起所有主要操作的默认分支,包括当有人克隆存储库时默认检出的分支。

转移项目

如果您想将项目转移到 GitHub 中的另一个用户或组织,则可以在存储库设置页面的相同“选项”选项卡底部找到一个“转移所有权”选项,允许您执行此操作。

Transfer a project to another GitHub user or Organization
图 124. 将项目转移到另一个 GitHub 用户或组织

如果您要放弃项目并且有人想要接手,或者您的项目越来越大并且想要将其移入组织,这将非常有用。

这不仅将存储库及其所有观察者和星标移动到另一个位置,还将从您的 URL 设置重定向到新位置。它还将重定向来自 Git 的克隆和获取,而不仅仅是 Web 请求。

scroll-to-top