# Git ```{admonition} 准备 :class: important 在学习 `Git` 时最好拥有 [GitHub](https://github.com/)/[Gitee](https://gitee.com/) 账户 [^id2] ;同时在本机中拥有 [Git](https://git-scm.com/) 软件,以下所有命令行操作都是在 `Git bash` 中执行的。 ``` ```{toctree} :hidden: :numbered: Github 和 Git 的密匙准备 <./git/start> 基础操作 <./git/basic> .gitignore 文件以及其他文件 <./git/plus> 分支与合并 <./git/branch> 数据恢复以及返回机制 <./git/recall> 远程仓库的交互 <./git/remote_repository> 标签的使用 <./git/tag> 扩展 <./git/extend> Gitee <./gitee/index> 问题集 <./question/index> ``` ## Git 是什么? `Git` 是版本控制系统。 ### 直接记录快照,而非差异比较 `Git` 和其它版本控制系统(包括 `Subversion` 和近似工具)的主要差别在于 `Git` 对待数据的方式。从概念上来说,其它大部分系统以文件变更列表的方式存储信息,这类系统( `CVS` 、 `Subversion` 、 `Perforce` 、 `Bazaar` 等等) 将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异 (它们通常称作 基于差异 *(delta-based)* 的版本控制)。 ```{image} ./img/version-control-figure4.png :alt: 存储每个文件与初始版本的差异 ``` `Git` 不按照以上方式对待或保存数据。反之, `Git` 更像是把数据看作是对小型文件系统的一系列快照。 在 `Git` 中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。为了效率,如果文件没有修改, `Git` 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 `Git` 对待数据更像是一个 **快照流**。 ```{image} ./img/version-control-figure5.png :alt: 存储项目随时间改变的快照 ``` ### 近乎所有操作都是本地执行 在 `Git` 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。 ### Git 保证完整性 `Git` 中所有的数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在 `Git` 不知情时更改任何文件内容或目录内容。 这个功能建构在 `Git` 底层,是构成 `Git` 哲学不可或缺的部分。 若你在传送过程中丢失信息或损坏文件, `Git` 就能发现。 `Git` 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。 这是一个由 40 个十六进制字符(0-9 和 a-f)组成的字符串,基于 `Git` 中文件的内容或目录结构计算出来。 实际上, `Git` 数据库中保存的信息都是以 *文件内容* 的哈希值来索引,而不是文件名。 ### Git 一般只添加数据 你执行的 `Git` 操作,几乎只往 `Git` 数据库中 *添加* 数据。 你很难使用 `Git` 从数据库中删除数据,也就是说 `Git` 几乎不会执行任何可能导致文件不可恢复的操作。 同别的 `CVS` 一样, *未提交更新时有可能丢失或弄乱修改的内容* 。但是一旦你提交快照到 `Git` 中, 就难以再丢失数据,特别是如果你定期的推送数据库到其它仓库的话。 ### 三种状态 `Git` 控制下的文件三种状态: 已提交 *(committed)* 、已修改 *(modified)* 和 已暂存 *(staged)*。这会让我们的 `Git` 项目拥有三个阶段:工作区、暂存区以及 `Git` 目录(本地 `Git` 仓库)。 - 已修改 *(modified)* :表示修改了文件,但还没保存到数据库中。 - 已暂存 *(staged)* :表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。 - 已提交 *(committed)* :表示数据已经安全地保存在本地数据库中。 ```{image} ./img/version-control-figure6.png :alt: 工作目录、暂存区域以及 Git 仓库 ``` 工作区是对项目的某个版本独立提取出来的内容。 这些从 `Git` 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。 暂存区是一个文件,保存了下次将要提交的文件列表信息,一般在 `Git` 仓库目录中。 按照 `Git` 的术语叫做“索引”,不过一般说法还是叫“暂存区”。 `Git` 仓库目录是 `Git` 用来保存项目的元数据和对象数据库的地方。 这是 `Git` 中最重要的部分,从其它计算机克隆仓库时,复制的就是这里的数据。 基本的 `Git` 工作流程如下: 1. 在工作区中修改文件。 2. 将你想要下次提交的更改选择性地暂存,这样只会将更改的部分添加到暂存区。 3. 提交更新,找到暂存区的文件,将快照永久性存储到 `Git` 目录。 [^id2]: 拥有GitHub/Gitee账户的目的是拥有远程仓库。当然,读者也可以自己搭建一个远程仓库。