Skip to content
This page has been auto-translated and may contain errors.View in English

Git 是什么?

docs.scrimba.com

你几乎肯定手动进行过版本控制。一个包含 report.docxreport_final.docxreport_final_v2.docxreport_final_ACTUAL.docx 的文件夹就是版本控制,只不过是最糟糕的那种。你无法看出这两个文件之间发生了什么变化,无法合并两个人同时进行的编辑,也肯定无法恢复三个版本前删除的好段落。

Git 能够正确地解决这个问题。它是一个工具,可以记录项目随时间推移的快照,这样你的整个历史就存储在一个地方,而不是一堆副本。这个工具本身是一个小程序,存放在你自己的计算机上:你在终端中输入以 git 开头的命令,它会以文本形式回复。

Git 能为你做什么

Git 的核心功能是维护项目的时间线。每当你到达值得保存的地点时,你就记录一个 提交:每个文件的快照,加上一条简短的消息说明发生了什么变化以及为什么。稍后你可以回顾这条时间线,精确地看到项目是如何到达现状的。以下是一条真实的时间线,由 git log 打印,这是列出项目提交的命令(--oneline 标志将每个提交缩短为一行):

bash
$ git log --oneline
a1b2c3d 添加密码强度计量器
9f8e7d6 修复注册表单验证
5c4b3a2 设置项目结构

这是项目历史中三个保存的点,最新的在最上面,每个都有一个短 ID 和其作者编写的消息。(在每个这样的例子中,以 $ 开头的行是在终端中输入的命令,不包括 $ 本身,下面的行是 Git 的回复。)你将在接下来的几章中学到每个生成和读取这个历史的命令。现在要记住的想法是 Git 正在将你的工作记录为 一系列你总是可以返回的快照

一旦你的项目拥有这样的历史,许多事情就成为可能了。你可以看到发生了什么变化以及谁改变了它。你可以在一旁尝试一个冒险的想法,如果不行就干净地丢弃它。你可以将整个项目及其完整历史交给其他人。当两个人编辑相同的代码时,Git 可以合并他们的工作,并标记他们不一致的地方,以便人类可以解决。这四项能力,即历史、安全实验、共享和合并工作,是 Git 在几乎所有专业代码库下运行的全部原因。

实际上,团队在日常工作中会不断依赖这条时间线。任何规模的每个变化都从自己的 分支 开始,这是一条独立的历史线,你可以在其中工作而不会影响主代码。当变化准备好时,有人审查它,然后它会被合并回主分支。审查、分支和合并是在 Git 中工作的日常节奏,它们都基于上面的快照时间线。本手册的其余部分按照你遇到的顺序逐步讲解每一个部分。

一个细节对之后的所有内容都很重要:每个提交都存储了你跟踪文件的完整状态,该时刻的完整快照。人们经常认为 Git 只保存版本之间的差异,但实际上每个提交都拥有整个项目。Git 通过仅存储一次每个唯一的文件内容来保持这个成本较低,因此重复使用未更改文件的提交只会指向已保存的副本,而一千个文件中只有一个改变的快照不会复制其他 999 个文件。每个提交也记录了它之前的提交的 ID,即它的 父提交,这是 Git 如何将快照链接到可以向后遍历的历史的方式。这个父链接是几乎所有其他内容的骨干:分支、合并和历史浏览都是基于遵循这些指针构建的。你将在"历史"和"分支"章节中看到完整的对象模型。

JunoGit 能为你做什么 Git 将你的项目记录为一系列称为提交的快照,每个都带有说明发生了什么变化的消息。一旦这个历史存在,你就可以回顾它、安全地进行实验、共享它,并与其他人合并工作。一堆 final_v2_ACTUAL 副本是 Git 被创建来结束的问题,我保证第一次删除其中一个时感觉很棒。
JunoGit 能为你做什么 提交是一个快照加一条消息,历史是它们的时间线。每天你都从这条时间线中分出一个分支来进行更改,获得审查,然后合并回去。在你的脑海中保持一个不断增长的快照时间线的心理模型;你学到的每个命令都是要么添加到它,要么从它读取。
JunoGit 能为你做什么 每个提交都存储整个项目状态并指向其父提交,这是 Git 遍历历史的方式。相同的文件内容在提交之间存储一次并共享,所以快照保持廉价。牢记父指针想法,因为分支和合并是同一想法穿着不同的外衣。

Git 和 GitHub 是不同的东西

这一点在开始时会迷惑几乎每个人,所以这里用简明的术语说一下。Git 是版本控制工具。它在你自己的计算机上运行,它记录你的提交,它不需要互联网连接也不需要账户就能工作。GitHub 是一个在线存储 Git 仓库的网站,并在其周围添加了一些功能:一个共享代码的地方、相互审查变化、报告问题和协作。

感受区别的最清晰方式:你可以每天使用 Git,在笔记本上提交和分支,而无需创建 GitHub 账户。GitHub 只有在你想将仓库放在共享位置以便其他人或其他机器可以访问时才会出现。Git 是引擎;GitHub 是一个托管它所生成内容的地方。 还有其他地方,例如 GitLabBitbucket,它们都在下面托管相同的 Git 仓库。

这两个概念模糊的原因是,大多数人在同一时刻遇到 Git 和 GitHub,在他们的第一天从 GitHub 克隆一个项目。许多人留下的印象是 git push 意味着"发送到 GitHub",而它实际上意味着"发送到你配置的任何远程",那个远程大多数时候恰好是 GitHub。在你的脑海中将两者分开会在你第一次将 Git 与不同的主机一起使用时或根本不使用主机时获得回报。

JunoGit 和 GitHub 是不同的东西 Git 是你计算机上记录你提交的工具。GitHub 是一个在线存储 Git 项目的网站,以便人们可以共享和审查它们。你可以完全不使用 GitHub 账户就使用 Git。如果你从这一页只记住一件事,让它成为这个,因为混淆它们会导致很多早期的混乱。
JunoGit 和 GitHub 是不同的东西 Git 是你机器上的版本控制引擎;GitHub 是一个流行的地方来托管它所生成的内容,还有 GitLab 和 Bitbucket。git push 发送到你设置的任何远程,这通常出于习惯是 GitHub。保持分离,当项目存在于其他地方时你不会被难住。
JunoGit 和 GitHub 是不同的东西 Git 知道提交、分支和引用;GitHub 在托管副本的基础上分层拉取请求、问题和合并按钮。GitHub 添加的任何东西都不是 Git 命令,这就是为什么你在网站上打开拉取请求,而不是使用 git。在你的脑海中将两者分开,大多数看起来像 GitHub 魔法的东西都会变回普通引用。

Git 的来源

Git 的历史解释了很多关于它为什么以这样的方式工作的原因。它在 2005 年由 Linus Torvalds 编写,他就是启动 Linux 的人。Linux 内核是由散布在世界各地的数千个志愿者构建的,几年来他们一直使用一个称为 BitKeeper 的商业工具来协调所有这些工作,该工具背后的公司允许开源项目免费使用。

在 2005 年,这种免费安排破裂了,内核社区突然没有了工具来管理其庞大、快速发展的代码库。当时没有其他可用的工具能够跟上。所以 Torvalds 从内核工作中抽身出来,花了几周时间编写自己的版本控制工具,目标明确,形成于解决这个确切问题。

他希望它是 分布式的,这样每个贡献者都可以在自己的机器上拥有完整的项目历史,并可以在不与中央服务器通信的情况下工作。他希望它 快速,足够快地处理内核大小的项目,而不会让人们等待。他希望它能保证 完整性,这样没有人可以悄悄改变历史,也没有磁盘错误可以破坏项目而不被注意到。

这些目标是 Git 今天的行为方式的原因。当你 clone 一个项目时,你获得了它的全部历史来使用,这是分布式目标的实际应用:你可以在没有 wifi 的飞机上进行提交、分支和浏览历史。每个提交都用从其精确内容计算的指纹标记,所以如果单个字节曾经改变,指纹就不再匹配,Git 会注意到。Torvalds 在 2005 年匆匆做出的设计决定是你现在每次使用 Git 时都依赖的决定。

完整性保证驱动了整个设计。每个提交都由哈希标识,一个固定长度的指纹,从提交的完整内容计算,包括其父提交的 ID。因为父提交的 ID 进入子提交的哈希,哈希形成一条链:改变旧提交中的任何内容,其哈希改变,这改变了它之后每个提交的哈希。这就是使 Git 历史防篡改的原因。它还意味着提交的 ID 是其精确内容的指纹,这就是为什么你看到那些十六进制字符串,比如 a1b2c3d,而不是整洁的提交数字 42。

JunoGit 的来源 Linus Torvalds 在 2005 年为 Linux 内核编写了 Git,在该项目一直使用的工具停止免费提供之后。他构建它是为了实现分布式、快速和防止腐败。这就是为什么 clone 给你完整的历史来离线使用,以及为什么每个提交都获得一个指纹。这是对你将使用多年的工具的有用背景。
JunoGit 的来源 Git 在 2005 年从 Linux 内核中问世,为数千个贡献者构建,没有中央服务器,这就是为什么它的整个模型是分布式的。每个克隆都承载完整的历史,所以你本地分支和提交,并在你选择时同步。当一个 Git 默认值感觉奇怪时,"它是为内核设计的"通常解释了它。
JunoGit 的来源 Git 在 2005 年出自 Torvalds 的两周冲刺,当时内核失去了对 BitKeeper 的访问权限,有三个目标:分布式、快速、完整性检查。每个提交的哈希从其内容加上其父提交的哈希计算,所以 ID 形成一条防篡改链。当你想知道为什么 Git 做出了某个选择时,"它是为 Linux 内核构建的"通常是答案。

本手册接下来去哪里

心理模型到位后,轨道的其余部分是关于进行工作。你的第一个仓库 从零开始:打开终端,如果你的机器没有 Git 就安装它,并将一个文件夹变成你可以提交的仓库。从那里你将学到保存变化的日常循环,然后分支、合并和 GitHub 上的协作流程。如果一个术语曾经让你困惑,词汇表 中有这些文档中每个 Git 术语的简短定义。