版本控制工具Git的简史和基础

126 阅读10分钟

一、关于版本控制

  什么是“版本控制”?版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。如果你是位图形或网页设计师,可能会需要保存某一幅图片或页面布局文件的所有修订版本(这或许是你非常渴望拥有的功能),采用版本控制系统(VCS)是个明智的选择。 有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。 使用版本控制系统通常还意味着,就算你乱来一气把整个项目中的文件改的改删的删,你也照样可以轻松恢复到原先的样子。 但额外增加的工作量却微乎其微。

1.分布式版本控制系统

  Git属于分布式版本控制系统(Distributed Version Control System,简称 DVCS), 在这类系统中,像 Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

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

二、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 的时候,请努力分清你对其它版本管理系统的已有认识,如Subversion和Perforce 等;这么做能帮助你使用工具时避免发生混淆。Git 在保存和对待各种信息的时候与其它版本控制系统有很大差异,尽管操作起来的命令形式非常相近,理解这些差异将有助于防止你使用中的困惑。

1.直接记录快照,而非差异比较

  Git更像是把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。Git对待数据更像是一个 快照流。

  这是 Git 与几乎所有其它版本控制系统的重要区别。因此Git 重新考虑了以前每一代版本控制系统延续下来的诸多方面。Git 更像是一个小型的文件系统,提供了许多以此为基础构建的超强工具,而不只是一个简单的 VCS。


2.所有操作都是本地执行

  在Git中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。如果你习惯于所有操作都有网络延时开销的集中式版本控制系统,Git在这方面会让你感到速度之神赐给了Git超凡的能量。 因为你在本地磁盘上就有项目的完整历史,所以大部分操作看起来瞬间完成。

  举个例子,要浏览项目的历史,Git 不需外连到服务器去获取历史,然后再显示出来——它只需直接从本地数据库中读取。 你能立即看到项目历史。如果你想查看当前版本与一个月前的版本之间引入的修改,Git 会查找到一个月前的文件做一次本地的差异计算,而不是由远程服务器处理或从远程服务器拉回旧版本文件再来本地处理。

  这也意味着你离线或者没有网络时,几乎可以进行任何操作。 如你在飞机或火车上想做些工作,你能愉快地提交,直到有网络连接时再上传。 如你回家后VPN客户端不正常,你仍能工作。 使用其它系统,做到如此是不可能或很费力的。比如,用Perforce,你没有连接服务器时几乎不能做什么事;用Subversion和 CVS,你能修改文件,但不能向数据库提交修改(因为你的本地数据库离线了)。 这看起来不是大问题,但是你可能会惊喜地发现它带来的巨大的不同。


3.Git保证完整性

  Git中所有数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在Git不知情时更改任何文件内容或目录内容。这个功能建构在Git 底层,是构成Git哲学不可或缺的部分。若你在传送过程中丢失信息或损坏文件,Git 就能发现。

  Git用以计算校验和的机制叫做SHA-1散列(hash,哈希)。这是一个由40 个十六进制字符(0-9和a-f)组成的字符串,基于Git中文件的内容或目录结构计算出来。 SHA-1哈希看起来是这样:

24b9da6552252987aa493b52f8696cd6d3b00373

  Git中使用这种哈希值的情况很多,你将经常看到这种哈希值。实际上,Git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。


4.Git一般只添加数据

  执行的Git操作,几乎只往Git数据库中增加数据。很难让Git 执行任何不可逆操作,或者让它以任何方式清除数据。同别的VCS 一样,未提交更新时有可能丢失或弄乱修改的内容;但是一旦你提交快照到Git 中,就难以再丢失数据,特别是如果你定期的推送数据库到其它仓库的话。

  这使得我们使用Git 成为一个安心愉悦的过程,因为我们深知可以尽情做各种尝试,而没有把事情弄糟的危险。 更深度探讨Git如何保存数据及恢复丢失数据的话题,请参考撤消操作。


5.三种状态

  Git有三种状态,你的文件可能处于其中之一:已提交(committed)、已修改(modified)和已暂存(staged)。已提交表示数据已经安全的保存在本地数据库中。 已修改表示修改了文件,但还没保存到数据库中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

由此引入Git项目的三个工作区域的概念:Git仓库、工作目录以及暂存区域。

  • Git仓库目录是Git用来保存项目的元数据和对象数据库的地方。这是Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。
  • 工作目录是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。
  • 暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。 有时候也被称作“索引”,不过一般说法还是叫暂存区域。

6.基本的 Git 工作流程如下:

  1. 在工作目录中修改文件。
  2. 暂存文件,将文件的快照放入暂存区域。
  3. 提交更新,找到暂存区域的文件,将快照永久性存储到Git仓库目录。

  如果Git目录中保存着特定版本的文件,就属于已提交状态。 如果作了修改并已放入暂存区域,就属于已暂存状态。 如果自上次取出后,作了修改但还没有放到暂存区域,就是已修改状态。在Git 基础一章,你会进一步了解这些状态的细节,并学会如何根据文件状态实施后续操作,以及怎样跳过暂存直接提交。

7.命令行

  Git有多种使用方式。你可以使用原生的命令行模式,也可以使用GUI 模式,这些GUI软件也能提供多种功能。我们将使用命令行模式。 这是因为首先,只有在命令行模式下你才能执行Git的所有命令,而大多数的GUI 软件只实现了Git所有功能的一个子集以降低操作难度。 如果你学会了在命令行下如何操作,那么你在操作GUI 软件时应该也不会遇到什么困难,但是,反之则不成立。 此外,由于每个人的想法与侧重点不同,不同的人常常会安装不同的GUI软件,但所有 人一定要会用命令行工具。


本教程参考《Pro Git》中文版以及官方文档

《Pro Git》中文电子版下载链接:https://pan.baidu.com/s/1l-7tvEWLq9o6tvboKF8s9w 提取码:cawk

官网:https://git-scm.com/

官方文档:https://git-scm.com/doc