1 版本控制系统
版本控制系统是一种记录一个或若干个文件内容变化,以便将来查阅特定版本修订情况的系统。一般情况下,对软件源代码的文件进行版本控制,但实际上,你可以对任何类型的文件进行版本控制。
有了版本控制系统,你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。
1.1 本地版本控制系统
许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。这么做唯一的好处就是简单,但是特别容易犯错。有时候会混淆所在的工作目录,一不小心就会写错文件或者覆盖意想外的文件。
在早期,为了解决这个问题,人们就开发了许多本地版本控制系统,这些系统大都是采用某种简单的数据库来记录文件的历次更新差异。
1.2 集中式版本控制系统
接下来又遇到一个问题,如何让在不同系统上的开发者协同工作?于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。这类系统,诸如 CVS、Subversion 以及 Perforce 等,都有一个单一、集中管理的服务器,上面保存着所有文件的修订版本,而协同工作的开发者都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。
现在,每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松地管理每个开发者的权限,并且管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。
然而这么做,最显而易见的缺点是中央服务器的单点故障。如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据——包括项目的整个变更历史,只剩下开发者在各自机器上保留的单独快照。本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。
1.3 分布式版本控制系统
为了消除单点故障风险,分布式版本控制系统(Distributed Version Control System,简称 DVCS)出现了。在这类系统中,像 Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这么一来,任何一处协同工作用到的服务器发生故障,都可以用任何一个镜像出来的本地仓库恢复。因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。
更进一步,这类系统大都可以指定和多个不同的远端代码仓库进行交互。籍此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。你可以根据需要设定不同的协作流程,比如层次模型式的工作流,而这在集中式系统中是无法实现的。
2 Git 简史
Linux 内核开源项目有着为数众广的开发者。绝大多数的 Linux 内核维护时间与精力都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。所以到了 2002 年,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码。
2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。这就迫使Linux 开源社区开发出自己的版本控制系统。他们对新的系统制订了若干目标:
- 速度
- 简单的设计
- 对非线性开发模式的强力支持(允许成千上万个并行开发的分支)
- 完全分布式
- 有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
自诞生于 2005 年以来,Git 日臻成熟完善,在高度易用的同时,仍然保留着初期设定的目标。它的操作速度很快,极其适合管理大项目,有着令人难以置信的非线性分支管理能力。
3 Git 基础
3.1 直接记录快照,而非差异比较
Git 和集中式版本控制系统(Subversion)的主要差别在于对待数据的方法上。从概念上来区分,集中式版本控制系统以文件变更列表的方式存储信息。这些系统把保存的信息看作是一组基本文件和每个文件随时间推移而逐步累积的差异。
Git 是把数据看作是对小型文件系统的一组快照。每次提交更新或保存项目状态时,Git 会把当时的全部文件制作成一个快照并保存这个快照的索引。如果文件没有修改,Git 只保留一个链接指向之前存储的文件(节省空间)。Git 对待数据的方式是快照流。
这是 Git 与其它版本控制系统的重要区别。它更像是一个小型的文件系统,提供了许多以此为基础构建的工具。
3.2 几乎所有操作都在本地执行
在 Git 中的绝大多数操作都只需要访问本地文件和资源。相对于所有操作都在有网络延时开销的集中式版本控制系统而言,Git 在操作上具有显著的速度优势。因为在本地磁盘上就保存着项目的完整历史,所以大部分操作看起来像是瞬间就可以完成的。
举个例子,要浏览项目的历史,Git 不需要连到服务器去获取历史,然后再显示出来——它只需直接从本地数据库中读取。所以你能立即看到项目历史。如果你想查看当前版本与一个月前的版本之间引入的修改,Git 会查找到一个月前的文件做一次本地的差异计算。操作都在本地,速度能不快吗O(∩_∩)O~
如果你在飞机或火车上想做些开发工作,仍然可以愉快地提交,直到有网络连接时再上传。用 Subversion 或 CVS,你能修改文件,但不能向服务器提交修改(因为没有网络咯)。
3.3 保证完整性
所有数据在存储前都计算校验和,然后以校验和来引用。这个功能建构在 Git 底层。如果在传送过程中丢失信息或文件损坏,Git 就能发现这些问题。
Git 使用 SHA-1 散列(hash,哈希)计算校验和。这是一个由 40 个十六进制字符(0-9 和 a-f)组成字符串,基于 Git 中文件的内容或目录结构计算出来。SHA-1 哈希后的结果看起来像是这样:
24b9da6552252987aa493b52f8696cd6d3b00373
实际上,Git 的数据库中保存的信息都是以文件内容的哈希值来索引的,而不是文件名。
3.4 一般只添加数据
执行的 Git 操作,几乎只往 Git 数据库中增加数据。一旦提交快照到 Git 中,就可以避免数据丢失。
3.5 文件的三种状态
文件有三种状态:
- 已提交(committed)- 表示数据已经安全地保存在本地数据库中。
- 已修改(modified)- 表示修改了文件,但还没保存到数据库中。
- 已暂存(staged)- 表示对一个已修改文件的当前版本做了标记,它会被包含在下一次提交的快照中。
由此引入 项目的三种工作区域:Git 仓库、工作目录以及暂存区域。
仓库目录用来保存项目的元数据和对象数据库。这是 Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。
工作目录是对项目的某个版本独立提取出来的内容。这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供使用或修改。
暂存区域是一个文件,保存了下次将要提交的文件列表信息,一般在 Git 仓库目录中。也可称为索引。
基本的 Git 工作流程如下:
- 在工作目录中修改文件。
- 暂存文件,将文件的快照放入暂存区域。
- 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。
如果 Git 目录中保存着的特定版本文件,就属于已提交状态。如果作了修改并已放入暂存区域,就属于已暂存状态。如果自上次取出后,作了修改但还没有放到暂存区域,就是已修改状态。
4 命令行
在我们的介绍中,将使用命令行模式。这是因为,只有在命令行模式下才能执行 Git 的 所有 命令,而大多数的 GUI 软件只实现了 Git 所有功能的一个子集以降低操作难度。所以如果你学会了在命令行下如何操作,那么在操作 GUI 软件也将得心应手O(∩_∩)O~
5 安装 Git
5.1 在 Linux 上安装
可以使用发行版包含的基础软件包管理工具来安装。如果以
centos7 上为例,你可以使用 yum:
$ sudo yum install git
如果在基于 Debian 的发行版上,请使用 apt-get:
$ sudo apt-get install git
5.2 在 Mac 上安装
在 Mac 上安装 Git 有多种方式。最简单的方法是安装 Xcode Command Line Tools。Mavericks (10.9) 或更高版本的系统中,在 Terminal 里尝试首次运行 git 命令即可。如果没有安装过命令行开发者工具,将会提示安装。
如果想安装更新的版本,可以使用二进制安装程序。官方维护的 OSX Git 安装程序可以在 Git 官方网站下载,网址为 http://git-scm.com/download/mac。
也可以将它作为 GitHub for Mac 的一部分来安装。它们的图形化 Git 工具有一个安装命令行工具的选项。可以从 GitHub for Mac 网站下载该工具,网址为 http://mac.github.com。
5.3 在 Windows 上安装
在 Windows 上安装 Git 也有几种安装方法。官方版本可以在 Git 官方网站下载。打开 http://gitscm.com/download/win,下载会自动开始。要注意这是一个名为 Git for Windows 的项目(也叫做msysGit),和 Git 是分别独立的项目;更多信息请访问 http://msysgit.github.io/。
另一个简单的方法是安装 GitHub for Windows。该安装程序包含图形化和命令行版本的 Git。它也能支持 Powershell,提供了稳定的凭证缓存和健全的 CRLF 设置。可以在 GitHub for Windows 网站下载,网址为 http://windows.github.com。
6 初次运行 Git 前的配置
安装好 Git 之后,就可以定制你的 Git 环境。每台计算机上只需要配置一次,程序升级时会保留配置信息。
Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。这些变量存储在三个不同的位置:
- /etc/gitconfig 文件:包含系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system 选项的 git config 时,它会从此文件读写配置变量。
- ~/.gitconfig 或 ~/.config/git/config 文件:只针对当前用户。 可以传递 --global 选项让 Git 读写此文件。
- 当前使用仓库的 Git 目录中的 config 文件(就是 .git/config):只针对这个仓库。
每一个级别覆盖上一级别的配置,所以 .git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。
在 Windows 系统中,Git 会查找 $HOME 目录下(一般情况下是
C:\Users$USER)的 .gitconfig 文件。Git 同样也会寻找 /etc/gitconfig 文件,但只限于 MSys 的根目录下,即安装 Git 时所选的目标路径位置。
6.1 用户信息
安装完 Git 后,首先要设置你的用户名称与邮件地址。每一次 Git 的提交都会使用这些信息,且不可更改:
$ git config --global user.name "Deniro Li"
$ git config --global user.email lisq@example.com
再次强调,如果使用了 --global 选项,那么该命令只需要运行一次,因为之后无论做什么, Git 都会使用这些信息。当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 --global 选项的命令来配置。
很多 GUI 工具都会在第一次运行时帮助你配置这些信息。
6.2 文本编辑器
现在可以配置默认文本编辑器了,当 Git 需要你输入信息时会调用它。如果未配置,Git 会使用操作系统默认的文本编辑器,通常是 Vim。如果你想使用不同的文本编辑器,例如 Emacs,可以这样做:
$ git config --global core.editor emacs
6.3 检查配置信息
如果想要检查你的配置,可以使用 git config --list 命令来列出所有 Git 当时能找到的配置。
你可能会看到重复的变量名,因为 Git 会从不同的文件中读取同一个配置(例如:/etc/gitconfig 与~/.gitconfig)。这种情况下,Git 会使用它找到的每一个变量的最后一个配置。
也可以通过输入 git config <key>: 来检查 Git 的某一项配置:
7 获取帮助
使用 Git 时,如果需要获取帮助,有三种方法可以找到 Git 命令的使用手册:
$ git help <verb>
$ git <verb> --help
$ man git-<verb
举个例子,如果要想获得 config 命令的手册,可以执行:
$ git help config
这些命令很好用,因为你随时随地都可以使用而无需联网。如果你觉得手册还不够用,可以尝试在Freenode IRC 服务器( irc.freenode.net )的 #git 或 #github 频道寻求帮助。这些频道经常有上百人在线,他们都精通 Git 并且乐于助人。