标签 Git 下的文章

这些有用的技巧将改变你使用这个流行的版本控制系统的工作方式。

Git 是目前最常见的版本控制系统之一,无论是私有系统还是公开托管的网站,都在使用它进行各种开发工作。但无论我对 Git 的使用有多熟练,似乎总有一些功能还没有被发现,下面是改变我使用 Git 工作方式的七个技巧。

1、Git 中的自动更正

我们有时都会打错字,但如果启用了 Git 的自动更正功能,就可以让 Git 自动修正打错的子命令。

假设你想用 git status 检查状态,却不小心输入了 git stats。正常情况下,Git 会告诉你 stats 不是一条有效的命令:

$ git stats
git: ‘stats’ is not a git command. See ‘git --help’.

The most similar command is
status

为了避免类似的情况发生,请在 Git 配置中启用 Git 自动更正功能:

$ git config --global help.autocorrect 1

如果你希望这个命令只适用于你当前的版本库,请省略 --global 选项。

这条命令启用了自动更正功能。更深入的教程可以在 Git Docs 中找到,但尝试一下和上面一样的错误命令,就能很好地了解这个配置的作用:

$ git stats
git: ‘stats’ is not a git command. See ‘git --help’.
On branch master
Your branch is up to date with ‘origin/master’.

nothing to commit, working tree clean

Git 现在不会建议使用其他子命令,而是直接运行最上面的建议,在本例中是 git status

2、计算你的提交量

你需要计算提交数量可能有很多原因。例如,许多开发者通过计算提交数量来判断何时该增加构建版本号,或者只是想了解项目的进展情况。

要计算提交数量其实很简单直接,下面是 Git 的命令:

$ git rev-list --count branch-name

在上面的命令中,branch-name 应该是当前版本库中有效的分支名称:

$ git rev-list –count master
32
$ git rev-list –count dev
34

3、优化你的仓库

你的代码仓库不仅对你有价值,对你的组织也有价值。你可以通过一些简单的做法来保持你的版本库的清洁和更新。其中一个最好的做法是 使用 .gitignore 文件。使用这个文件,就是告诉 Git 不要存储许多不需要的文件,比如二进制文件、临时文件等等。

为了进一步优化你的版本库,你可以使用 Git 的垃圾收集功能:

$ git gc --prune=now --aggressive

当你或你的团队大量使用 pullpush 命令时,这条命令就会起到帮助作用。

这个命令是一个内部工具,可以清理仓库中无法访问或 “孤儿” Git 对象。

4、备份未被跟踪的文件

大多数时候,删除所有未被跟踪的文件是安全的。不过很多时候,你不仅要删除,还要为你的未跟踪文件创建一个备份,以备以后需要。

通过 Git 和一些 Bash 命令管道,可以很容易地为你的未被跟踪的文件创建一个压缩包:

$ git ls-files --others --exclude-standard -z |\
xargs -0 tar rvf ~/backup-untracked.zip

上面的命令制作了一个名为 backup-untracked.zip 的存档(并排除了 .gitignore 中列出的文件)。

5、了解你的 .git 文件夹

每个版本库都有一个 .git 文件夹。它是一个特殊的隐藏文件夹。

$ ls -a
. … .git

Git 的工作主要依赖于两个部分:

  1. 工作树(你当前签出的文件状态)。
  2. 你的 Git 仓库的路径(即你的 .git 文件夹的位置,其中包含版本信息)。

这个文件夹存储了所有的引用和其他重要的细节,比如配置、仓库数据、HEAD 状态、日志等等。

如果你删除这个文件夹,你的源代码的当前状态不会被删除,但你的远程信息,如你的项目历史记录,会被删除。删除这个文件夹意味着你的项目(至少是本地副本)不再处于版本控制之下。这意味着你不能跟踪你的变化;你不能从远程拉取或推送。

一般来说,不需要在 .git 文件夹里做什么,也没有什么应该做的。它是由 Git 管理的,基本上被认为是个禁区。然而,这个目录里有一些有趣的工件,包括 HEAD 的当前状态。

$ cat .git/HEAD
ref: refs/heads/master

它还可能包含对你的存储库的描述:

$ cat .git/description

这是一个未命名的仓库,编辑这个 description 文件可以命名这个仓库。

Git 钩子文件夹(hooks)也在这里,里面有一些钩子示例文件。你可以阅读这些示例来了解通过 Git 钩子可以实现什么,你也可以 阅读 Seth Kenlon 的 Git 钩子介绍

6、查看另一个分支的文件

有时你想查看另一个分支的文件的内容。用一个简单的 Git 命令就可以实现,而且不需要切换分支。

假设你有一个名为 README.md 的文件,它在 main 分支中,而你正在 dev 分支上工作。

使用下面的 Git 命令,你可以在终端上完成:

$ git show main:README.md

一旦你执行了这个命令,你就可以在你的终端上查看文件的内容。

7、在 Git 中搜索

只需一个简单的命令,你就可以像专业人士一样在 Git 中搜索。更棒的是,即使你不确定是在哪个提交或分支上做的修改,也可以在 Git 中搜索。

$ git rev-list --all | xargs git grep -F 'string'

例如,假设你想在你的版本库中搜索 font-size: 52 px; 这个字符串:

$ git rev-list –all | xargs git grep -F 'font-size: 52 px;'
F3022…9e12:HtmlTemplate/style.css: font-size: 52 px;
E9211…8244:RR.Web/Content/style/style.css: font-size: 52 px;

试试这些技巧

希望这些高级技巧对你有用,提高你的工作效率,为你节省很多时间。

你有喜欢的 Git 小技巧 吗?在评论中分享吧。


via: https://opensource.com/article/20/10/advanced-git-tips

作者:Rajeev Bera 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

可以使用相同的机器用于工作和个人的 Git 提交,而无需手动重置你的配置。

Git 的 git config 命令可以让你为 Git 设置仓库或全局选项。它有很多选项,其中的一个选项 includeIf 在你使用在 Git 时有双重角色时非常方便,比如说,你既是全职的开发者,又在业余时间为开源项目做贡献。在这种情况下,大多数人都不想为两个角色使用一个共同的配置,或者,至少,他们肯定希望保持配置的某些部分是不同的,尤其是当他们在两个角色中使用同一台计算机时。

我的情况就是这样,所以我在 Git 配置中保留了两组不同的邮件 ID。这样一来,在我工作场所的项目仓库中提交的内容就会使用我办公室的邮件 ID,而在我个人 GitHub 帐户中提交的内容则使用我个人的邮件 ID。

以下是我的全局配置(维护在 $HOME/.gitconfig)中的一个片段,我将在下文中介绍。

[includeIf "gitdir:~/priv_scm/"]
        path = ~/priv_scm/.gitconfig
[includeIf "gitdir:~/work_scm/"]
        path = ~/work_scm/.gitconfig

什么是 includeIf?

includeIf.condition.path 变量,是 include 配置指令的一部分,允许你有条件地设置自定义配置。同时,自定义配置的路径也可以作为指令的一部分来设置。

这个指令支持三个关键字:gitdirgitdir/Ionbranch。我将简单解释一下 gitdir,我在上面的代码片段中使用了它。你可以在文档中了解其他两个关键词。

includeIf 指令中使用 gitdir 关键字会对模式进行条件检查。根据规则,如果当前工作目录与 gitdir 中指定的目录模式相匹配,那么它就会从给定的路径中选取配置。我将在配置片段上应用这个规则来展示它是如何被应用的。

在配置片段中,你可以看到一个简单的模式,~/,它与 gitdir 关键字一起使用。这个模式会被存储在 $HOME 环境变量中的值所替代。

如何使用它

如果你使用同一个系统在 GitHub 或 GitLab 上的开源项目上工作,并在工作中提交到 Git 仓库,你可以有两个顶级目录,比如 $HOME/priv_scm$HOME/work_scm。在这两个目录中,你可以有两个单独的 .gitconfig 文件,其中包含与你的 user.nameuser.email 相关的设置。然而,它们也可以包含存储在 $HOME 的全局 .gitconfig 中,它可以保存两个环境通用的所有自定义项。

这里是一个例子 $HOME/priv_scm/.gitconfig 的片段:

$ cat $HOME/priv_scm/.gitconfig
[user]
    name  = Ramanathan Muthiah
    email = <personal-mailid-goes-here>

有了这个配置,你就可以切换目录,并开始在开源项目上工作,而无需手动重置一些与 Git 相关的配置。这些更改会在主 .gitconfig 中借助 includeIf 条件指令自动处理。

Git 小贴士

希望这个小贴士能帮助你组织 Git 项目。你最喜欢的 Git 小贴士是什么?请在评论中分享吧!


via: https://opensource.com/article/20/10/git-config

作者:Ramanathan M 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

采用这些 Git 协作策略,让团队工作更高效。

Git 非常有助于小团队管理他们的软件开发进度,但有些方法能让你变得更高效。我发现了许多有助于我的团队的最佳实践,尤其是当不同 Git 水平的新人加入时。

在你的团队中正式确立 Git 约定

每个人都应当遵循对于分支命名、标记和编码的规范。每个组织都有自己的规范或者最佳实践,并且很多建议都可以从网上免费获取,而重要的是尽早选择合适的规范并在团队中遵循。

同时,不同的团队成员的 Git 水平参差不齐。你需要创建并维护一组符合团队规范的基础指令,用于执行通用的 Git 操作。

正确地合并变更

每个团队成员都需要在一个单独的功能分支上开发。但即使是使用了单独的分支,每个人也会修改一些共同的文件。当把更改合并回 master 分支时,合并通常无法自动进行。可能需要手动解决不同的人对同一文件不同变更的冲突。这就是你必须学会如何处理 Git 合并的原因。

现代编辑器具有协助解决 Git 合并冲突的功能。它们对同一文件的每个部分提供了合并的各种选择,例如,是否保留你的更改,或者是保留另一分支的更改,亦或者是全部保留。如果你的编辑器不支持这些功能,那么可能是时候换一个代码编辑器了。

经常变基你的功能分支

当你持续地开发你的功能分支时,请经常对它做 变基 rebase rebase master。这意味着要经常执行以下步骤:

git checkout master
git pull
git checkout feature-xyz  # 假设的功能分支名称
git rebase master  # 可能需要解决  feature-xyz 上的合并冲突

这些步骤会在你的功能分支上重写历史(这并不是件坏事)。首先,它会使你的功能分支获得 master 分支上当前的所有更新。其次,你在功能分支上的所有提交都会在该分支历史的顶部重写,因此它们会顺序地出现在日志中。你可能需要一路解决遇到的合并冲突,这也许是个挑战。但是,这是解决冲突最好的时机,因为它只影响你的功能分支。

在解决完所有冲突并进行回归测试后,如果你准备好将功能分支合并回 master,那么就可以在再次执行上述的变基步骤几次后进行合并:

git checkout master
git pull
git merge feature-xyz

在此期间,如果其他人也将和你有冲突的更改推送到 master,那么 Git 合并将再次发生冲突。你需要解决它们并重新进行回归测试。

还有一些其他的合并哲学(例如,只使用合并而不使用变基以防止重写历史),其中一些甚至可能更简单易用。但是,我发现上述方法是一个干净可靠的策略。提交历史日志将以有意义的功能序列进行排列。

如果使用“纯合并”策略(上面所说的,不进行定期的变基),那么 master 分支的历史将穿插着所有同时开发的功能的提交。这样混乱的历史很难回顾。确切的提交时间通常并不是那么重要。最好是有一个易于查看的历史日志。

在合并前压扁提交

当你在功能分支上开发时,即使再小的修改也可以作为一个提交。但是,如果每个功能分支都要产生五十个提交,那么随着不断地增添新功能,master 分支的提交数终将无谓地膨胀。通常来说,每个功能分支只应该往 master 中增加一个或几个提交。为此,你需要将多个提交 压扁 Squash 成一个或者几个带有更详细信息的提交中。通常使用以下命令来完成:

git rebase -i HEAD~20  # 查看可进行压扁的二十个提交

当这条命令执行后,将弹出一个提交列表的编辑器,你可以通过包括 遴选 pick 压扁 squash 在内的数种方式编辑它。“遴选”一个提交即保留这个提交。“压扁”一个提交则是将这个提交合并到前一个之中。使用这些方法,你就可以将多个提交合并到一个提交之中,对其进行编辑和清理。这也是一个清理不重要的提交信息的机会(例如,带错字的提交)。

总之,保留所有与提交相关的操作,但在合并到 master 分支前,合并并编辑相关信息以明确意图。注意,不要在变基的过程中不小心删掉提交。

在执行完诸如变基之类的操作后,我会再次看看 git log 并做最终的修改:

git commit --amend

最后,由于重写了分支的 Git 提交历史,必须强制更新远程分支:

git push -f

使用标签

当你完成测试并准备从 master 分支部署软件到线上时,又或者当你出于某种原因想要保留当前状态作为一个里程碑时,那么可以创建一个 Git 标签。对于一个积累了一些变更和相应提交的分支而言,标签就是该分支在那一时刻的快照。一个标签可以看作是没有历史记录的分支,也可以看作是直接指向标签创建前那个提交的命名指针。

所谓的“配置控制”就是在不同的里程碑上保存代码的状态。大多数项目都有一个需求,能够重现任一里程碑上的软件源码,以便在需要时重新构建。Git 标签为每个代码的里程碑提供了一个唯一标识。打标签非常简单:

git tag milestone-id -m "short message saying what this milestone is about"
git push --tags   # 不要忘记将标签显式推送到远程

考虑这样一种情况:Git 标签对应的软件版本已经分发给客户,而客户报告了一个问题。尽管代码库中的代码可能已经在继续开发,但通常情况下为了准确地重现客户问题以便做出修复,必须回退到 Git 标签对应的代码状态。有时候新代码可能已经修复了那个问题,但并非一直如此。通常你需要切换到特定的标签并从那个标签创建一个分支:

git checkout milestone-id        # 切换到分发给客户的标签
git checkout -b new-branch-name  # 创建新的分支用于重现 bug

此外,如果带附注的标记和带签名的标记有助于你的项目,可以考虑使用它们。

让软件运行时打印标签

在大多数嵌入式项目中,从代码版本构建出的二进制文件有固定的名称,这样无法从它的名称推断出对应的 Git 标签。在构建时“嵌入标签”有助于将未来发现的问题精准地关联到特定的构建版本。在构建过程中可以自动地嵌入标签。通常,git describe 生成的标签字符串会在代码编译前插入到代码中,以便生成的可执行文件能够在启时时输出标签字符串。当客户报告问题时,可以指导他们给你发送启动时输出的内容。

总结

Git 是一个需要花时间去掌握的复杂工具。使用这些实践可以帮助团队成功地使用 Git 协作,无论他们的知识水平。


via: https://opensource.com/article/20/7/git-best-practices

作者:Ravi Chandran 选题:lujun9972 译者:LazyWolfLin 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

使用 .gitignore 文件是提高代码和 Git 仓库质量的最佳实践之一。

我注意到很多开发者没有使用 .gitignore 文件,尽管使用 .gitignore 文件来指定你不希望 Git 在版本控制中跟踪的文件是最佳实践之一。.gitignore 可以提高代码质量,所以你不应该忽略版本库中的 .gitignore

什么是 .gitignore?

Git 仓库中的文件可以是:

  1. 未跟踪的:未被暂存或提交的变更。
  2. 跟踪的:已暂存或提交的变更。
  3. 忽略的:你让 Git 忽略的文件。

有些文件你希望 Git 忽略,不要在你的版本库中跟踪它,这些文件包括许多自动生成的或特定于平台的文件,以及其他本地配置文件,如:

  1. 含有敏感信息的文件
  2. 编译出的代码,如 .dll.class
  3. 系统文件,如 .DS_StoreThumbs.db
  4. 含有临时信息的文件,如日志、缓存等。
  5. 生成的文件,如 dist 文件夹。

如果你不想让 Git 跟踪版本库中的某些文件,不过这不能通过 Git 命令做到。(虽然你可以用 git rm 命令停止跟踪一个文件,比如 git rm --cached。)相反,你需要使用 .gitignore 文件,这是一个告诉 Git 不要跟踪哪些文件的文本文件。

创建 .gitignore 文件很简单,只需创建一个文本文件并命名为 .gitignore。记得在文件名的开头有一个点(.)。就这样就完成了。

编写 .gitignore 文件的规则

根据文档,“.gitignore 文件中的每一行都指定了一个模式。”

在此上下文中,“模式”可以指一个特定的文件名,或者指文件名的某些部分结合上通配符。换句话说,example.txt 是匹配名为 example.txt 的文件的有效模式,而 ex*txt 是匹配名为 example.txt 以及 export.txt 的文件的有效模式。

以下是一些帮助你正确设置 .gitignore 文件的基本规则:

  1. 任何以哈希(#)开头的行都是注释。
  2. \ 字符可以转义特殊字符。
  3. / 字符表示该规则只适用于位于同一文件夹中的文件和文件夹。
  4. 星号(*)表示任意数量的字符(零个或更多)。
  5. 两个星号(**)表示任意数量的子目录。
  6. 一个问号(?)代替零个或一个字符。
  7. 一个感叹号(!)会反转特定的规则(即包括了任何被前一个模式排除的文件)。
  8. 空行会被忽略,所以你可以用它们来增加空间,使你的文件更容易阅读。
  9. 在末尾添加 / 会忽略整个目录路径。

本地与全局 .gitignore 文件的比较

有两种类型的 .gitignore 文件:

  • 本地:放在 Git 仓库的根目录下,只在该仓库中工作,并且必须提交到该仓库中。
  • 全局:放在你的主目录根目录下,影响你在你的机器上使用的每个仓库,不需要提交。

很多开发者在项目仓库中使用本地的 .gitignore 文件,但很少有人使用全局的 .gitignore 文件。使用全局文件最显著的优势是,你不需要提交就可以使用它,而且做一个改动会影响你所有的版本库。

Git 忽略的优势

除了确保特定的文件不被 Git 追踪之外,使用 .gitignore 文件还有其他好处。

  1. 通过忽略不需要的文件,它可以帮助你保持代码库的干净。
  2. 它可以控制代码库的大小,这在你正在做一个大项目的时候特别有用。
  3. 你的每一次提交、推送和拉取请求都将是干净的。

结束语

Git 很强大,但归根结底,它只是一个计算机程序而已。使用最佳实践并保持你的代码仓库稳定是一个团队的努力,其中要做到一件事就是使用 .gitignore 文件。


via: https://opensource.com/article/20/8/dont-ignore-gitignore

作者:Rajeev Bera 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Git 核心的附加价值之一就是编辑历史记录的能力。与将历史记录视为神圣的记录的版本控制系统不同,在 Git 中,我们可以修改历史记录以适应我们的需要。这为我们提供了很多强大的工具,让我们可以像使用重构来维护良好的软件设计实践一样,编织良好的提交历史。这些工具对于新手甚至是有经验的 Git 用户来说可能会有些令人生畏,但本指南将帮助我们揭开强大的 git-rebase 的神秘面纱。

值得注意的是:一般建议不要修改公共分支、共享分支或稳定分支的历史记录。编辑特性分支和个人分支的历史记录是可以的,编辑还没有推送的提交也是可以的。在编辑完提交后,可以使用 git push -f 来强制推送你的修改到个人分支或特性分支。

尽管有这么可怕的警告,但值得一提的是,本指南中提到的一切都是非破坏性操作。实际上,在 Git 中永久丢失数据是相当困难的。本指南结尾介绍了在犯错误时进行纠正的方法。

设置沙盒

我们不想破坏你的任何实际的版本库,所以在整个指南中,我们将使用一个沙盒版本库。运行这些命令来开始工作。 1

git init /tmp/rebase-sandbox
cd /tmp/rebase-sandbox
git commit --allow-empty -m"Initial commit"

如果你遇到麻烦,只需运行 rm -rf /tmp/rebase-sandbox,并重新运行这些步骤即可重新开始。本指南的每一步都可以在新的沙箱上运行,所以没有必要重做每个任务。

修正最近的提交

让我们从简单的事情开始:修复你最近的提交。让我们向沙盒中添加一个文件,并犯个错误。

echo "Hello wrold!" >greeting.txt
git add greeting.txt
git commit -m"Add greeting.txt"

修复这个错误是非常容易的。我们只需要编辑文件,然后用 --amend 提交就可以了,就像这样:

echo "Hello world!" >greeting.txt
git commit -a --amend

指定 -a 会自动将所有 Git 已经知道的文件进行暂存(例如 Git 添加的),而 --amend 会将更改的内容压扁到最近的提交中。保存并退出你的编辑器(如果需要,你现在可以修改提交信息)。你可以通过运行 git show 看到修复的提交。

commit f5f19fbf6d35b2db37dcac3a55289ff9602e4d00 (HEAD -> master)
Author: Drew DeVault 
Date:   Sun Apr 28 11:09:47 2019 -0400

    Add greeting.txt

diff --git a/greeting.txt b/greeting.txt
new file mode 100644
index 0000000..cd08755
--- /dev/null
+++ b/greeting.txt
@@ -0,0 +1 @@
+Hello world!

修复较旧的提交

--amend 仅适用于最近的提交。如果你需要修正一个较旧的提交会怎么样?让我们从相应地设置沙盒开始:

echo "Hello!" >greeting.txt
git add greeting.txt
git commit -m"Add greeting.txt"

echo "Goodbye world!" >farewell.txt
git add farewell.txt
git commit -m"Add farewell.txt"

看起来 greeting.txt 像是丢失了 "world"。让我们正常地写个提交来解决这个问题:

echo "Hello world!" >greeting.txt
git commit -a -m"fixup greeting.txt"

现在文件看起来正确,但是我们的历史记录可以更好一点 —— 让我们使用新的提交来“修复”(fixup)最后一个提交。为此,我们需要引入一个新工具:交互式变基。我们将以这种方式编辑最后三个提交,因此我们将运行 git rebase -i HEAD~3-i 代表交互式)。这样会打开文本编辑器,如下所示:

pick 8d3fc77 Add greeting.txt
pick 2a73a77 Add farewell.txt
pick 0b9d0bb fixup greeting.txt

# Rebase f5f19fb..0b9d0bb onto f5f19fb (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# f, fixup <commit> = like "squash", but discard this commit's log message

这是变基计划,通过编辑此文件,你可以指导 Git 如何编辑历史记录。我已经将该摘要削减为仅与变基计划这一部分相关的细节,但是你可以在文本编辑器中浏览完整的摘要。

当我们保存并关闭编辑器时,Git 将从其历史记录中删除所有这些提交,然后一次执行一行。默认情况下,它将选取(pick)每个提交,将其从堆中召唤出来并添加到分支中。如果我们对此文件根本没有做任何编辑,则将直接回到起点,按原样选取每个提交。现在,我们将使用我最喜欢的功能之一:修复(fixup)。编辑第三行,将操作从 pick 更改为 fixup,并将其立即移至我们要“修复”的提交之后:

pick 8d3fc77 Add greeting.txt
fixup 0b9d0bb fixup greeting.txt
pick 2a73a77 Add farewell.txt
技巧:我们也可以只用 f 来缩写它,以加快下次的速度。

保存并退出编辑器,Git 将运行这些命令。我们可以检查日志以验证结果:

$ git log -2 --oneline
fcff6ae (HEAD -> master) Add farewell.txt
a479e94 Add greeting.txt

将多个提交压扁为一个

在工作时,当你达到较小的里程碑或修复以前的提交中的错误时,你可能会发现写很多提交很有用。但是,在将你的工作合并到 master 分支之前,将这些提交“压扁”(squash)到一起以使历史记录更清晰可能很有用。为此,我们将使用“压扁”(squash)操作。让我们从编写一堆提交开始,如果要加快速度,只需复制并粘贴这些:

git checkout -b squash
for c in H e l l o , ' ' w o r l d; do
    echo "$c" >>squash.txt
    git add squash.txt
    git commit -m"Add '$c' to squash.txt"
done

要制作出一个写着 “Hello,world” 的文件,要做很多事情!让我们开始另一个交互式变基,将它们压扁在一起。请注意,我们首先签出了一个分支来进行尝试。因此,因为我们使用 git rebase -i master 进行的分支,我们可以快速变基所有提交。结果:

pick 1e85199 Add 'H' to squash.txt
pick fff6631 Add 'e' to squash.txt
pick b354c74 Add 'l' to squash.txt
pick 04aaf74 Add 'l' to squash.txt
pick 9b0f720 Add 'o' to squash.txt
pick 66b114d Add ',' to squash.txt
pick dc158cd Add ' ' to squash.txt
pick dfcf9d6 Add 'w' to squash.txt
pick 7a85f34 Add 'o' to squash.txt
pick c275c27 Add 'r' to squash.txt
pick a513fd1 Add 'l' to squash.txt
pick 6b608ae Add 'd' to squash.txt

# Rebase 1af1b46..6b608ae onto 1af1b46 (12 commands)
#
# Commands:
# p, pick <commit> = use commit
# s, squash <commit> = use commit, but meld into previous commit
技巧:你的本地 master 分支独立于远程 master 分支而发展,并且 Git 将远程分支存储为 origin/master。结合这种技巧,git rebase -i origin/master 通常是一种非常方便的方法,可以变基所有尚未合并到上游的提交!

我们将把所有这些更改压扁到第一个提交中。为此,将第一行除外的每个“选取”(pick)操作都更改为“压扁”(squash),如下所示:

pick 1e85199 Add 'H' to squash.txt
squash fff6631 Add 'e' to squash.txt
squash b354c74 Add 'l' to squash.txt
squash 04aaf74 Add 'l' to squash.txt
squash 9b0f720 Add 'o' to squash.txt
squash 66b114d Add ',' to squash.txt
squash dc158cd Add ' ' to squash.txt
squash dfcf9d6 Add 'w' to squash.txt
squash 7a85f34 Add 'o' to squash.txt
squash c275c27 Add 'r' to squash.txt
squash a513fd1 Add 'l' to squash.txt
squash 6b608ae Add 'd' to squash.txt

保存并关闭编辑器时,Git 会考虑片刻,然后再次打开编辑器以修改最终的提交消息。你会看到以下内容:

# This is a combination of 12 commits.
# This is the 1st commit message:

Add 'H' to squash.txt

# This is the commit message #2:

Add 'e' to squash.txt

# This is the commit message #3:

Add 'l' to squash.txt

# This is the commit message #4:

Add 'l' to squash.txt

# This is the commit message #5:

Add 'o' to squash.txt

# This is the commit message #6:

Add ',' to squash.txt

# This is the commit message #7:

Add ' ' to squash.txt

# This is the commit message #8:

Add 'w' to squash.txt

# This is the commit message #9:

Add 'o' to squash.txt

# This is the commit message #10:

Add 'r' to squash.txt

# This is the commit message #11:

Add 'l' to squash.txt

# This is the commit message #12:

Add 'd' to squash.txt

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Apr 28 14:21:56 2019 -0400
#
# interactive rebase in progress; onto 1af1b46
# Last commands done (12 commands done):
#    squash a513fd1 Add 'l' to squash.txt
#    squash 6b608ae Add 'd' to squash.txt
# No commands remaining.
# You are currently rebasing branch 'squash' on '1af1b46'.
#
# Changes to be committed:
#   new file:   squash.txt
#

默认情况下,这是所有要压扁的提交的消息的组合,但是像这样将其保留肯定不是你想要的。不过,旧的提交消息在编写新的提交消息时可能很有用,所以放在这里以供参考。

提示:你在上一节中了解的“修复”(fixup)命令也可以用于此目的,但它会丢弃压扁的提交的消息。

让我们删除所有内容,并用更好的提交消息替换它,如下所示:

Add squash.txt with contents "Hello, world"

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Apr 28 14:21:56 2019 -0400
#
# interactive rebase in progress; onto 1af1b46
# Last commands done (12 commands done):
#    squash a513fd1 Add 'l' to squash.txt
#    squash 6b608ae Add 'd' to squash.txt
# No commands remaining.
# You are currently rebasing branch 'squash' on '1af1b46'.
#
# Changes to be committed:
#   new file:   squash.txt
#

保存并退出编辑器,然后检查你的 Git 日志,成功!

commit c785f476c7dff76f21ce2cad7c51cf2af00a44b6 (HEAD -> squash)
Author: Drew DeVault
Date:   Sun Apr 28 14:21:56 2019 -0400

    Add squash.txt with contents "Hello, world"

在继续之前,让我们将所做的更改拉入 master 分支中,并摆脱掉这一草稿。我们可以像使用 git merge 一样使用 git rebase,但是它避免了创建合并提交:

git checkout master
git rebase squash
git branch -D squash

除非我们实际上正在合并无关的历史记录,否则我们通常希望避免使用 git merge。如果你有两个不同的分支,则 git merge 对于记录它们合并的时间非常有用。在正常工作过程中,变基通常更为合适。

将一个提交拆分为多个

有时会发生相反的问题:一个提交太大了。让我们来看一看拆分它们。这次,让我们写一些实际的代码。从一个简单的 C 程序 2 开始(你仍然可以将此代码段复制并粘贴到你的 shell 中以快速执行此操作):

cat <<EOF >main.c
int main(int argc, char *argv[]) {
    return 0;
}
EOF

首先提交它:

git add main.c
git commit -m"Add C program skeleton"

然后把这个程序扩展一些:

cat <<EOF >main.c
#include &ltstdio.h>

const char *get_name() {
    static char buf[128];
    scanf("%s", buf);
    return buf;
}

int main(int argc, char *argv[]) {
    printf("What's your name? ");
    const char *name = get_name();
    printf("Hello, %s!\n", name);
    return 0;
}
EOF

提交之后,我们就可以准备学习如何将其拆分:

git commit -a -m"Flesh out C program"

第一步是启动交互式变基。让我们用 git rebase -i HEAD~2 来变基这两个提交,给出的变基计划如下:

pick 237b246 Add C program skeleton
pick b3f188b Flesh out C program

# Rebase c785f47..b3f188b onto c785f47 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# e, edit <commit> = use commit, but stop for amending

将第二个提交的命令从 pick 更改为 edit,然后保存并关闭编辑器。Git 会考虑一秒钟,然后向你建议:

Stopped at b3f188b...  Flesh out C program
You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue

我们可以按照以下说明为提交添加新的更改,但我们可以通过运行 git reset HEAD^ 来进行“软重置” 3 。如果在此之后运行 git status,你将看到它取消了提交最新的提交,并将其更改添加到工作树中:

Last commands done (2 commands done):
   pick 237b246 Add C program skeleton
   edit b3f188b Flesh out C program
No commands remaining.
You are currently splitting a commit while rebasing branch 'master' on 'c785f47'.
  (Once your working directory is clean, run "git rebase --continue")

Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

  modified:   main.c

no changes added to commit (use "git add" and/or "git commit -a")

为了对此进行拆分,我们将进行交互式提交。这使我们能够选择性地仅提交工作树中的特定更改。运行 git commit -p 开始此过程,你将看到以下提示:

diff --git a/main.c b/main.c
index b1d9c2c..3463610 100644
--- a/main.c
+++ b/main.c
@@ -1,3 +1,14 @@
+#include &ltstdio.h>
+
+const char *get_name() {
+    static char buf[128];
+    scanf("%s", buf);
+    return buf;
+}
+
 int main(int argc, char *argv[]) {
+    printf("What's your name? ");
+    const char *name = get_name();
+    printf("Hello, %s!\n", name);
     return 0;
 }
Stage this hunk [y,n,q,a,d,s,e,?]?

Git 仅向你提供了一个“大块”(即单个更改)以进行提交。不过,这太大了,让我们使用 s 命令将这个“大块”拆分成较小的部分。

Split into 2 hunks.
@@ -1 +1,9 @@
+#include <stdio.h>
+
+const char *get_name() {
+    static char buf[128];
+    scanf("%s", buf);
+    return buf;
+}
+
 int main(int argc, char *argv[]) {
Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?
提示:如果你对其他选项感到好奇,请按 ? 汇总显示。

这个大块看起来更好:单一、独立的更改。让我们按 y 来回答问题(并暂存那个“大块”),然后按 q 以“退出”交互式会话并继续进行提交。会弹出编辑器,要求输入合适的提交消息。

Add get_name function to C program

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# interactive rebase in progress; onto c785f47
# Last commands done (2 commands done):
#    pick 237b246 Add C program skeleton
#    edit b3f188b Flesh out C program
# No commands remaining.
# You are currently splitting a commit while rebasing branch 'master' on 'c785f47'.
#
# Changes to be committed:
#   modified:   main.c
#
# Changes not staged for commit:
#   modified:   main.c
#

保存并关闭编辑器,然后我们进行第二次提交。我们可以执行另一次交互式提交,但是由于我们只想在此提交中包括其余更改,因此我们将执行以下操作:

git commit -a -m"Prompt user for their name"
git rebase --continue

最后一条命令告诉 Git 我们已经完成了此提交的编辑,并继续执行下一个变基命令。这样就行了!运行 git log 来查看你的劳动成果:

$ git log -3 --oneline
fe19cc3 (HEAD -> master) Prompt user for their name
659a489 Add get_name function to C program
237b246 Add C program skeleton

重新排序提交

这很简单。让我们从设置沙箱开始:

echo "Goodbye now!" >farewell.txt
git add farewell.txt
git commit -m"Add farewell.txt"

echo "Hello there!" >greeting.txt
git add greeting.txt
git commit -m"Add greeting.txt"

echo "How're you doing?" >inquiry.txt
git add inquiry.txt
git commit -m"Add inquiry.txt"

现在 git log 看起来应如下所示:

f03baa5 (HEAD -> master) Add inquiry.txt
a4cebf7 Add greeting.txt
90bb015 Add farewell.txt

显然,这都是乱序。让我们对过去的 3 个提交进行交互式变基来解决此问题。运行 git rebase -i HEAD~3,这个变基规划将出现:

pick 90bb015 Add farewell.txt
pick a4cebf7 Add greeting.txt
pick f03baa5 Add inquiry.txt

# Rebase fe19cc3..f03baa5 onto fe19cc3 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
#
# These lines can be re-ordered; they are executed from top to bottom.

现在,解决方法很简单:只需按照你希望提交出现的顺序重新排列这些行。应该看起来像这样:

pick a4cebf7 Add greeting.txt
pick f03baa5 Add inquiry.txt
pick 90bb015 Add farewell.txt

保存并关闭你的编辑器,而 Git 将为你完成其余工作。请注意,在实践中这样做可能会导致冲突,参看下面章节以获取解决冲突的帮助。

git pull –rebase

如果你一直在由上游更新的分支 <branch>(比如说原始远程)上做一些提交,通常 git pull 会创建一个合并提交。在这方面,git pull 的默认行为等同于:

git fetch origin <branch>
git merge origin/<branch>

假设本地分支 <branch> 配置为从原始远程跟踪 <branch> 分支,即:

$ git config branch.<branch>.remote
origin
$ git config branch.<branch>.merge
refs/heads/<branch>

还有另一种选择,它通常更有用,并且会让历史记录更清晰:git pull --rebase。与合并方式不同,这基本上 4 等效于以下内容:

git fetch origin
git rebase origin/<branch>

合并方式更简单易懂,但是如果你了解如何使用 git rebase,那么变基方式几乎可以做到你想要做的任何事情。如果愿意,可以将其设置为默认行为,如下所示:

git config --global pull.rebase true

当你执行此操作时,从技术上讲,你在应用我们在下一节中讨论的过程……因此,让我们也解释一下故意执行此操作的含义。

使用 git rebase 来变基

具有讽刺意味的是,我最少使用的 Git 变基功能是它以之命名的功能:变基分支。假设你有以下分支:

A--B--C--D--> master
   \--E--F--> feature-1
      \--G--> feature-2

事实证明,feature-2 不依赖于 feature-1 的任何更改,它依赖于提交 E,因此你可以将其作为基础脱离 master。因此,解决方法是:

git rebase --onto master feature-1 feature-2

非交互式变基对所有牵连的提交都执行默认操作(pick 5 ,它只是简单地将不在 feature-1 中的 feature-2 中提交重放到 master 上。你的历史记录现在看起来像这样:

A--B--C--D--> master
   |     \--G--> feature-2
   \--E--F--> feature-1

解决冲突

解决合并冲突的详细信息不在本指南的范围内,将来请你注意另一篇指南。假设你熟悉通常的解决冲突的方法,那么这里是专门适用于变基的部分。

有时,在进行变基时会遇到合并冲突,你可以像处理其他任何合并冲突一样处理该冲突。Git 将在受影响的文件中设置冲突标记,git status 将显示你需要解决的问题,并且你可以使用 git addgit rm 将文件标记为已解决。但是,在 git rebase 的上下文中,你应该注意两个选项。

首先是如何完成冲突解决。解决由于 git merge 引起的冲突时,与其使用 git commit 那样的命令,更适当的变基命令是 git rebase --continue。但是,还有一个可用的选项:git rebase --skip。 这将跳过你正在处理的提交,它不会包含在变基中。这在执行非交互性变基时最常见,这时 Git 不会意识到它从“其他”分支中提取的提交是与“我们”分支上冲突的提交的更新版本。

帮帮我! 我把它弄坏了!

毫无疑问,变基有时会很难。如果你犯了一个错误,并因此而丢失了所需的提交,那么可以使用 git reflog 来节省下一天的时间。运行此命令将向你显示更改一个引用(即分支和标记)的每个操作。每行显示你的旧引用所指向的内容,你可对你认为丢失的 Git 提交执行 git cherry-pickgit checkoutgit show 或任何其他操作。


  1. 我们添加了一个空的初始提交以简化本教程的其余部分,因为要对版本库的初始提交进行变基需要特殊的命令(即git rebase --root)。
  2. 如果要编译此程序,请运行 cc -o main main.c,然后运行 ./main 查看结果。
  3. 实际上,这是“混合重置”。“软重置”(使用 git reset --soft 完成)将暂存更改,因此你无需再次 git add 添加它们,并且可以一次性提交所有更改。这不是我们想要的。我们希望选择性地暂存部分更改,以拆分提交。
  4. 实际上,这取决于上游分支本身是否已变基或删除/压扁了某些提交。git pull --rebase 尝试通过在 git rebasegit merge-base 中使用 “ 复刻点 fork-point ” 机制来从这种情况中恢复,以避免变基非本地提交。
  5. 实际上,这取决于 Git 的版本。直到 2.26.0 版,默认的非交互行为以前与交互行为稍有不同,这种方式通常并不重要。

via: https://git-rebase.io/

作者:git-rebase 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Git 和 GitHub 已经成为了开发者的基础工具,尤其是参与开源软件开发时经常会使用它们。但是在 Git 和 GitHub 使用过程中遇到的很多术语并没有标准的或约定俗成的中文译名,因此,我们根据 GitHubGit 等文档,并结合我们的翻译惯例,收集整理了 Git 和 GitHub 中常用术语的中文译名及其解释。

这里值得注意是术语有复刻、挂钩、议题、星标、变基、仓库等,这些术语之前要么经常中英文混杂使用,要么中文译法不确定,我们根据多年的翻译和开发经验,在 GitHub 译法的基础上进行斟酌,整理了如下的术语表供大家使用参考。此外,“复刻”这个翻译应该是我们 LCTT 首倡的;而“议题”这个对 issue 的译法也比之前的一些其它译法更为精准;“仓库”一词还有存储库、版本库等译法,但是仓库一词似乎更加合适。

受让人 assignee

分配到某个议题的用户。

追溯 blame

Git 中的“追溯”功能描述对文件每行的最新修改,一般会显示修订、作者和时间。这很有用,例如,可以跟踪何时添加了功能,或者哪个提交导致了特定漏洞。

分支 branch

分支是仓库的平行版本。它包含在仓库中,但不影响主要或 master 分支,可让你自由工作而不中断“即时”版本。在执行所需的更改后,可以将分支合并回 master 分支以发布更改。

检出 checkout

你可以在命令行上使用 git checkout 创建新分支,将当前的工作分支更改为不同的分支,甚至使用 git checkout [branchname] [path to file]从不同的分支切换到不同版本的文件。“检出”操作会使用对象数据库中的树对象或 blob 更新工作树的全部或部分,以及更新索引和 HEAD(如果整个工作树指向新分支)。

优选 cherry-picking

从一系列更改(通常是提交)中选择一部分更改,并在不同的代码库上将它们记录为新的更改系列。在 Git 中,这通过 git cherry-pick 命令来执行,在另一个分支上解压缩现有提交引入的更改,并根据当前分支的提示将其记录为新提交。

清洁 clean

工作树在对应当前头部引用的版本时是清洁的。另请参阅“脏”。

克隆 clone

克隆是指存在于计算机上而非网站服务器其他位置的仓库副本,或者是复制的操作。在克隆时,可在首选编辑器中编辑文件,使用 Git 跟踪更改而无需保持在线。你克隆的仓库仍与远程版本连接,以便当你在线时将本地更改推送到远程,以保持同步。

行为准则 code of conduct

为如何参与社区制定标准的文档。

代码所有者 code owner

被指定为部分仓库代码所有者的个人。当有人打开对代码所有者拥有的代码进行更改的拉取请求(非草稿模式)时,会自动申请代码所有者审查。

协作者 collaborator

协作者是受仓库所有者邀请参与,对仓库拥有读取和写入权限的人。

提交 commit

提交或“修订”是对一个文件(或一组文件)的个别更改。在进行提交以保存工作时,Git 会创建唯一的 ID(也称为 "SHA" 或“哈希”),用于记录提交的特定更改以及提交者和提交时间。提交通常包含一条提交消息,其中简要说明所做的更改。

提交作者 commit author

进行提交的用户。

提交 ID commit ID

也称为 SHA。用于识别提交的 40 字符校验和的哈希。

提交消息 commit message

随附于提交的简短描述性文字,用于沟通提交引入的更改。

持续集成 continuous integration

也称为 CI。在个人对 GitHub 上配置的仓库提交更改后运行自动化构建和测试的过程。CI 是软件开发中一种帮助检测错误的常用最佳实践。

贡献指南 contribution guidelines

说明人们应如何参与项目的文档。

贡献 contributions

GitHub 上的特定活动。

贡献者 contributor

贡献者是指对仓库没有协作者权限但参与过项目,并且他们打开的拉取请求已合并到仓库的人员。

默认分支 default branch

仓库中的基本分支,除非你指定不同的分支,否则会自动对它完成所有拉取请求和代码提交。此分支通常称为 master

游离的 HEAD detached HEAD

如果你操作的是游离的 HEAD,Git 将会警告你,这意味着 Git 不指向某个分支,并且你的任何提交都不会出现在提交历史记录中。例如,在检出并非任何特定分支最新提交的任意提交时,你操作的是“游离的 HEAD”。

差异 diff

差异是指两个提交之间的更改或保存的更改之间的区别,它将从视觉上描述文件自上次提交后添加或删除的内容。

dirty

工作树如果包含尚未提交到当前分支的更改,将被视为“脏”。

快进 fast-forward

快进是一种特殊类型的合并,在其中你有修订以及“合并”另一个分支的更改作为现有分支的子系。在这种情况下,你无法进行新的合并提交,而只是更新此修订。这在远程仓库的远程跟踪分支中经常发生。

功能分支 feature branch

用于试验新功能或修复未正式使用的议题的分支。也称为主题分支。

围栏代码块 fenced code block

你可以在代码块前后使用三个反引号 `,通过 GitHub Flavored Markdown 创建缩进代码块。

获取 fetch

在使用 git fetch 时,你将从远程仓库添加更改到本地工作分支,而不提交它们。与 git pull 不同,提取可让你在更改提交到本地分支之前先进行审查。

跟进(用户) following (users)

获取关于另一个用户的贡献和活动的通知。

强制推送 force push

一种使用本地更改覆盖远程仓库的 Git 推送,不管是否冲突。

复刻 fork

复刻是其他用户仓库在你的帐户上的个人副本。复刻允许你自由更改项目而不影响原始上游仓库。你也可以在上游仓库中打开拉取请求,并使复刻同步最新的更改,因为两个仓库仍然互相连接。

gitfile

一种普通的 .git 文件,始终位于工作树的根部,指向 Git 目录,包含整个 Git 仓库及其元数据。你可以在命令行上使用 git rev-parse --git-dir 查看仓库(实际仓库)的此文件。

HEAD

当前分支。

挂钩 hook

在多个 Git 命令正常执行时,对可选脚本进行标注以允许开发者添加功能或检查。通常,挂钩允许预先验证和潜在中止命令,并且允许在操作完成后再发事后通知。

实例 instance

组织包含在其配置和控制的虚拟机中的 GitHub 私有副本。

议题 issue

议题是提议的与仓库相关的改进、任务或问题。(对于公共仓库)任何人都可创建议题,然后由仓库协作者调解。每个议题都包含自己的讨论线程。你也可以使用标签将议题归类并分配到某人。

密钥指纹 key fingerprint

用于识别较长公钥的简短字节系列。

关键词 keyword

用在拉取请求中时关闭议题的特定文字。

标签 label

议题或拉取请求的标记。仓库随附一系列默认标签,但用户也可创建自定义标签。

LFS

Git Large File Storage。一种开源 Git 扩展,用于对大文件进行版本控制。

许可证 license

一种可随附于项目的文档,告知们能够对你的源代码执行哪些操作,不能执行哪些操作。

行注释 line comment

拉取请求内特定代码行上的评论。

主干 master

默认开发分支。只要创建 Git 仓库,就会创建一个名为 master 的分支,并且它会变为活动的分支。大多数情况下,这包含本地开发,但纯属惯例,而非必需。

提及 mention

一种通过在用户名前加上 @ 符号来发送给用户的通知。GitHub 上组织中的用户也可成为可提及的团队一部分。

合并 merge

合并是从一个分支(在相同的仓库中或来自一个分叉)提取更改,然后将其应用到另一个分支。这通常是作为“拉取请求”(可视为请求合并)或通过命令行完成。如果没有冲突的更改,可通过 GitHub.com web 界面使用拉取请求完成合并,或始终通过命令行完成。

合并冲突 merge conflict

合并的分支之间发生的差异。当人们对同一文件的同一行进行不同的更改时,或者一个人编辑某文件而另一个人删除该文件时,就会发生合并冲突。必须解决合并冲突后才可合并分支。

合并请求 merge request

合并请求(MR)是 GitLab 上类似于 GitHub 上的拉取请求的概念。

里程碑 milestone

一种跟踪仓库中议题或拉取请求组进度的方式。

镜像 mirror

仓库的新副本。

非快进 non-fast-forward

当仓库的本地副本未与上游仓库同步时,你在推送本地更改之前需要提取上游更改。

通知 notification

web 或电子邮件(根据你的设置)传送的更新,提供你感兴趣的活动的相关信息。

外部协作者 outside collaborator

已被授予访问一个或多个组织的仓库但对组织没有其他访问权限的用户,且不属于组织的成员。

开源 open source

开源软件是可供任何人自由使用、修改和共享(以修改和未修改的形式)的软件。今天,“开源”的概念通常扩展到软件以外,代表一种协作原则,其中工作材料在线供任何人分叉、修改、讨论和参与。

origin

默认上游仓库。大多数项目至少有一个它们跟踪的上游项目。默认情况下,源用于该目的。

所有者 owner

对组织有完全管理权限的组织成员。

私有贡献 private contributions

对私有(与公共相对)仓库的贡献。

私有仓库 private repository

私有仓库仅对仓库所有者和所有者指定的协作者可见。

生产分支 production branch

包含可使用或部署到应用程序或站点的最终更改的分支。

个人资料 profile

显示 GitHub 上用户活动相关信息的页面。

受保护分支 protected branch

受保护分支在仓库管理员选择保护的分支上禁止多项 Git 功能。必要检查未通过或必需审查未批准,不能对它们执行强制推送、删除和更改合并,或者不能从 GitHub web 界面上传文件到其中。受保护分支通常是默认分支。

公共贡献 public contributions

对公共(与私有相对)仓库的贡献。

公共仓库 public repository

公共仓库可供任何人查看,包括不是 GitHub 用户的人员。

拉取 pull

拉取是指提取与合并更改。例如,如果有人编辑了你操作的远程文件,你要将这些更改拉取到本地副本,以使其保持最新。另请参阅“提取”。

拉取权限 pull access

读取权限的同义词。

拉取请求 pull request

拉取请求(PR)是提议更改用户提交的仓库,然后被仓库协作者接受或拒绝。像议题一样,每个拉取请求都有自己的论坛。

拉取请求审查 pull request review

拉取请求中协作者批准更改或在拉取请求合并之前申请进一步更改的评论。

推送 push

推送是指将提交的更改发送到 GitHub.com 上的远程仓库。例如,如果你在本地更改内容,便可推送这些更改,让其他人访问。

推送分支 push a branch

成功将分支推送到远程仓库后,使用本地分支中的更改来更新远程分支。在你“推送分支”时,Git 将会到远程仓库中搜索分支的头部引用,并验证它是分支本地头部引用的直系原型。在验证后,Git 将拉取所有对象(从本地头部引用可获取,而远程仓库中缺失)到远程对象数据库,然后更新远程头部引用。如果远程头部不是本地头部的原型,推送将会失败。

推送权限 push access

写入权限的同义词。

读取权限 read access

对仓库的权限级别,允许用户拉取或者读取仓库中的信息。所有公共仓库向所有 GitHub 用户授予读取权限。拉取权限的同义词。

自述文件 README

包含仓库中文件相关信息的文本文件,通常是仓库访问者看到的第一个文件。自述文件连同仓库许可证、参与指南以及行为准则,帮助你交流要求和管理项目的参与。

变基 rebase

将一系列更改从一个分支重新应用到不同的基本分支,并将该分支的头部重置为结果。

发布 release

GitHub 封装软件并向用户提供软件的方式。

远程 remote

这是托管于服务器(很可能是 GitHub.com)上的仓库或分支版本。远程版本可以连接到本地克隆,以使更改保持同步。

远程仓库 remote repository

用于跟踪同一个项目但储存在其他位置的仓库。

远程 URL remote URL

存储代码的位置:GitHub、其他用户分支甚至不同服务器 上的仓库。

副本 replica

为主要 GitHub Enterprise 实例提供冗余的 GitHub Enterprise 实例。

仓库 repository

仓库是 GitHub 最基本的元素,最容易被想象成项目的文件夹。一个仓库包含所有项目文件(包括文档),并且存储每个文件的修订历史记录。仓库可有多个协作者,也可以是公共仓库或私有仓库。

仓库维护员 repository maintainer

管理仓库的人员。此人可帮助对议题分类,以及使用标签和其他功能管理仓库的工作,也可负责更新自述文件和参与文件。

解决 resolve

手动修复自动合并失败的操作。

还原 revert

恢复 GitHub 上的拉取请求时,新拉取请求会自动打开,其中有一个提交用于从原始合并的拉取请求恢复合并提交。在 Git 中,你可以使用 git revert 恢复提交。

审查 review

审查允许对仓库具有访问权限的其他人评论拉取请求中提议的更改、审批更改或在拉取请求合并之前请求进一步更改。

服务挂钩 service hook

也称为“Web 挂钩”。Web 挂钩是一种通知方式,只要仓库或组织上发生特定操作,就会发送通知到外部 web 服务器。

压扁 squash

将多个提交合并为一个。也是 Git 命令。

暂存实例 staging instance

在修改应用到实际 GitHub Enterprise 实例之前测试修改的一种方式。

状态 status

拉取请求中的可视表现形式,表示你的提交符合你参与的仓库所设定的条件。

星标 star

仓库的书签或赞赏表示。星标是项目受欢迎程度排名的手动方式。

主题分支 topic branch

开发者用来识别开发概念行的常规 Git 分支。由于分支很容易并且便宜,因此往往适合拥有多个小分支,每个小分支包含定义明确的概念,或者渐进但相关的更改。也可称为“特征分支”。

上游 upstream

在谈论分支或分叉时,原始仓库的主要分支通常被称为“上游”,因为它是其他更改的主要来源。你操作的分支/分叉则称为“下游”。也称为“源”。

上游分支 upstream branch

合并到所述分支的默认分支(或所述分支变基到的分支)。它通过 branch.<name>.remotebranch.<name>.merge 配置。如果 A 的上游分支是源/B,有时我们会说“A 在跟踪源/B”。

查看 watch

你可以关注仓库或议题,以便在议题或拉取请求有更新时接收通知。

web 挂钩 webhooks

Web 挂钩可让你构建或设置订阅 GitHub.com 上特定事件的 GitHub 应用程序。Web 挂钩提供一种通知方式,只要仓库或组织中发生特定操作,就会发送通知到外部 web 服务器。也称为“服务挂钩”。

写入权限 write access

对仓库的权限级别,可让用户推送或写入更改到仓库。