# 起步

2022年9月13日11分钟阅读

- FormalSciences/ComputerScience
- GettingStarted/VersionControl
- Git/Basics

我们会先了解一些版本控制工具的历史背景，然后试着让 Git 在你的系统上跑起来，直到最后配置好，可以正常开始开发工作。读完本章，你就会明白为什么 Git 会如此流行，为什么你应该立即开始使用它。

## 版本控制系统

版本控制系统（Version Control Systems，VCS）是一种记录一个或若干文件内容变化，以便将来查阅特定版本修订情况的系统。

### 本地版本控制系统

本地版本控制系统大多采用数据库来记录文件的历次更新差异。

其中最流行的一种叫做 RCS，现今许多计算机系统上都还看得到它的踪影。RCS 的工作原理是在硬盘上保存补丁集（补丁是指文件修订前后的变化）；通过应用所有的补丁，可以重新计算出各个版本的文件内容。

### 集中化的版本控制系统

为了解决本地版本控制系统无法协同工作的问题，集中化的版本控制系统（Centralized Version Control Systems，CVCS）应允而生。其采用一个单一集中管理的服务器，保存所有文件的修订版本；协作者通过客户端连接服务器，拉取最新文件或提交更新。

- 优点：相较于本地 VCS 来说。 现在，每个人都可以在一定程度上看到项目中的其他人正在做些什么。 而管理员也可以轻松掌控每个开发者的权限，并且管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。
- 缺点：显而易见的缺点是中央服务器的单点故障。例如宕机一小时，那么在这一小时内，谁都无法提交更新，也就无法协同工作；如果中心数据库所在的磁盘发生损坏，又没有做恰当备份，毫无疑问你将丢失所有数据——包括项目的整个变更历史，只剩下人们在各自机器上保留的单独快照。

### 分布式版本控制系统

为了解决集中化的版本控制系统的痛处，分布式版本控制系统（Distributed Version Control System，DVCS）面世了。分布式顾名思义，每一个节点都基于公认中心节点服务器的镜像拷贝，故每个节点都拥有代码仓库的完整信息。因此不存在中心节点故障无法工作、物理损坏无法恢复、日志历史不完整导致协作者无法相互协作。

更进一步，许多这类系统都可以指定和若干不同的远端代码仓库进行交互。籍此，你就可以在同一个项目中，分别和不同工作小组的人相互协作。 你可以根据需要设定不同的协作流程，比如层次模型式的工作流，而这在以前的集中式系统中是无法实现的。

## Git 简史

同生活中的许多伟大事物一样，Git 诞生于一个极富纷争大举创新的年代。

Linux 内核开源项目有着为数众多的参与者。 绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上（1991－2002 年间）。到 2002 年，整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码。

到了 2005 年，开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束，他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 这就迫使 Linux 开源社区（特别是 Linux 的缔造者 Linus Torvalds）基于使用 BitKeeper 时的经验教训，开发出自己的版本系统。 他们对新的系统制订了若干目标：

- 速度
- 简单的设计
- 对非线性开发模式的强力支持（允许成千上万个并行开发的分支）
- 完全分布式
- 有能力高效管理类似 Linux 内核一样的超大规模项目（速度和数据量）

自诞生于 2005 年以来，Git 日臻成熟完善，在高度易用的同时，仍然保留着初期设定的目标。 它的速度飞快，极其适合管理大项目，有着令人难以置信的非线性分支管理系统。

## Git 特性

那么，简单地说，Git 究竟是怎样的一个系统呢？它的主要特性是什么？

### 直接记录快照，而非差异比较

Git 与其他版本控制系统主要差别在于对待数据的方法；Git 直接记录快照，而非差异比较。Git 中每一次提交更新或保存项目状态都是对全部文件创建一个快照并保存这个快照的索引；如果文件没有修改，Git 则不再重新存储该文件，而是只保留一个链接指向之前存储的文件。Git 对待数据更像是一个快照流。

### 近乎所有操作都是本地执行

由于 Git 是分布式版本控制系统，在不对公认中心节点服务器操作的情况下，绝大多数操作都只需要访问本地文件资源。故 Git 大部分操作看起来瞬间完成，不存在网络延时。

### 保证数据完整性

Git 中所有的数据在存储前都用 SHA-1 散列（hash，哈希）计算校验和并以哈希值来索引，而不是文件名。这意味着不可能在 Git 不知情时更改任何文件内容或目录内容。

    // SHA-1 哈希
    24b9da6552252987aa493b52f8696cd6d3b00373

### 一般只添加数据

因为 Git 一般只添加数据，所以你很难让 Git 执行任何不可逆操作，或者让它以任何方式清除数据。

### Git 的三种状态

Git 有三种状态，你的文件可能处于其中之一： 已修改（modified） 、已暂存（staged）和已提交（committed）。

- 已修改：修改了文件，但还没保存到数据库中
- 已暂存：对一个已修改文件的当前版本做了标记，使之包含在下次提交的快照中。
- 已提交：数据已经安全地保存在本地数据库中。

这会让我们的 Git 项目拥有三个阶段：工作区（Working Directory）、暂存区（Staging Area） 以及 Git 目录（Repository）。

- 工作区：工作区对项目的某个版本独立提取出来的内容，放在磁盘上供你使用或修改。
- 暂存区：保存了下次将要提交的文件列表信息。
- Git 目录：Git 用来保存项目的元数据和对象数据库的地方。

所以 Git 的基本工作流程如下：

1. 在工作区中修改文件（已修改）。
2. 将你下次想要提交的更改选择性地暂存，这样只会将更改的部分添加到暂存区（已暂存）。
3. 提交更新，找到暂存区的文件，将快照永久性存储到 Git 目录（已提交）。

## Git 首次运行

Git 安装后首先要定制环境，仅需配置一次，升级时保留配置信息。

### Git 配置

1. 系统配置：包含系统上每一个用户及其仓库的通用配置。
2. 全局配置：只针对当前用户，对系统上所有仓库生效。
3. 仓库配置：仅对当前仓库生效，为默认选项。

配置文件作用域采用就近原则，每一个级别会覆盖上一级别的配置。修改不同的配置文件，需要在执行 git config 时传递不同参数。

    git config --system
    git config --global
    git config --local

### 用户信息

务必设置用户名和邮件地址，这一点至关重要，因为每一个 Git 提交都会使用这些信息，并且写入到每一次提交中，不可更改。

    git config --global user.name <user-name>
    git config --global user.email <email@email.com>

### 查看配置

    // 所有 Git 配置
    git config --list

    // 检查 Git 的某一项配置
    git config <key>

### 获取帮助

- Git 官方手册
- 开源指北

    git help <verb>
    git <verb> --help
    man git-<verb>

    // 简明的帮助文件
    git <verb> -h