Git 跟其余版本控制系统最大的优点就在于其高级的分支模型。git
Git 容许并且 鼓励 你在本地使用多个彻底独立的分支。这些分支的建立,合并和删除几乎均可以在几秒内完成。编程
这意味着你能够轻松的作以下操做:服务器
尤为是当你推送至远程仓库的时候,你没必要推送全部分支,你能够选择只推送少数你愿意分享的分支,固然若是你愿意,也能够推送全部分支。这一点倾向于让开发者在试验不少新的想法的时候免除发布本身的未成熟的试验计划的顾虑。markdown
固然,也有一些其余的系统能够部分实现上述的功能和优点,只是具体的执行会变的困难和容易出错。Git 让这些工做变得难以置信的简单,它在开发者学习其使用的同时就改变了开发者的工做模式。网络
Git 很快。Git 基本上全部的操做都在本地执行,这对于那些必须跟服务器通讯的集中式系统是一个巨大的速度优点。编程语言
Git 一开始是为了管理 Linux Kernel 的源代码设计的,这意味着他从第一天诞生就拥有了处理大型仓库的高效优点。Git 使用 C 语言编写,减轻了使用更高级别编程语言的 Runtime 带来的性能损耗。Git 最开始的两个重要的设计目标就是性能和速度。分布式
让咱们看一下与 SVN (一个通用的集中式存储版本控制系统,跟 CVS 和 Perforce 很像)相比下的常规操做的性能测试指标。这里指标是值越小,速度越快。工具
为了测试,咱们在亚马逊的 AWS 的一样的可用区上新建了两个 Large 类型的计算服务器实例。每个计算实例上都安装 Git 和 SVN。 咱们把 Ruby 的源代码仓库拷贝到了 Git 和 SVN 的计算服务器示例上,二者都执行通用的操做。性能
在有些状况下,二者的命令和实际效果并不能彻底对应起来。在这里,咱们在经常使用的操做中选择类似效果的匹配状况。例如,对于 “提交” 的测试,在 Git 中咱们也是计算 Push 的时间的。然而在大多数状况下,你可能实际上并不会在提交后立刻就推送到服务器上,这在 SVN 上是不可分割的操做。学习
下面表格中全部的时间单位都是秒。
操做 | 描述 | Git | SVN | 性能倍数 |
---|---|---|---|---|
提交文件 (A) | Add, commit and push 113 modified files (2164+, 2259-) | 0.64 | 2.60 | 4x |
提交图片 (B) | Add, commit and push 1000 1k images | 1.53 | 24.70 | 16x |
对比当前变更 | Diff 187 changed files (1664+, 4859-) against last commit | 0.25 | 1.09 | 4x |
对比最近的变更 | Diff against 4 commits back (269 changed/3609+,6898-) | 0.25 | 3.99 | 16x |
对比标签 | Diff two tags against each other (v1.9.1.0/v1.9.3.0) | 1.17 | 83.57 | 71x |
提交历史 (50) | Log of the last 50 commits (19k of output) | 0.01 | 0.38 | 31x |
提交历史 (所有) | Log of all commits (26,056 commits - 9.4M of output) | 0.52 | 169.20 | 325x |
提交历史 (文件) | Log of the history of a single file (array.c - 483 revs) | 0.60 | 82.84 | 138x |
更新 | Pull of Commit A scenario (113 files changed, 2164+, 2259-) | 0.90 | 2.82 | 3x |
Blame | Line annotation of a single file (array.c) | 1.91 | 3.04 | 1x |
你须要注意的是,这已是 SVN 最好的运行场景了 -- 一个没有任何负载的服务器,客户端和服务器之间的网络带宽达到 80MB/s。上文中的全部指标在受网络波动,或者在一个更差的网络环境下 SVN 的表现都更差,然而 Git 这边几乎全部的指标都不受影响。
很明显,在这些最经常使用的版本控制工具的操做中,甚至是在 SVN 的理想使用环境下,**Git 在不少方面都大幅领先 **。
一个 Git 比 SVN 慢的地方是初始化 clone 仓库。在这种状况下,Git 是在下载整个仓库历史而不是仅仅是最新版本的代码。上文中的表格所示,仅仅执行一次的操做影响并非很大。
操做 | 描述 | Git(Shallow Clone) | Git | SVN |
---|---|---|---|---|
Clone | Git Clone 以及 shallow clone(浅 clone) vs SVN checkout | 21.0 | 107.5 | 14.0 |
大小 (M) | 客户端在 clone/checkout 后的文件大小 (以 M 为单位) | 181.0 | 132.0 |
另一个有趣的点是,Git 和 SVN 在 Clone 或者 Checkout 到本地后的文件大小几乎差异不大,要知道对于 Git 来讲,本地但是包含了整个项目历史。这也展现了 Git 在文件压缩和存储上的超高效率。
Git 最棒的特性之一就是分布式。这意味着,你要 clone 整个仓库而不是仅仅 checkout 分支的最新头部版本。
在平常的使用场景中 Git 每每有多个备份。这意味着就算在使用一个中央存储式的工做流,每个用户都在本地有一个服务器上的完整备份。这里的任意一个版本均可以在服务器端数据损坏或者丢失的时候推送回服务器以挽救损失。事实上,只要你的仓库不是只有一个 copy,Git 就不会存在单点问题。
由于 Git 拥有分布式特性和极好的分支系统,你能够在此基础上轻松实现大量的工做流模型。
集中式存储的工做流很是常见,特别是对于那些从传统的集中式代码版本管理系统转过来使用 Git 的人。Git 同样能够提供这种工做形式:每次 Push 必需要更新到远程仓库的最新版本。因此说你们仍是像之前同样使用集中式存储的工做流往同一个服务器上 Push 代码依然没问题。
另一个常见的 Git 工做流是整合工做流。主要的仓库有一个单一的开发者维护(维护者)。其余若干开发者从这个仓库 clone,而后推送到他们本身的彻底独立的仓库里面,最后请求维护者从主要仓库 Pull 那些他们在各自的仓库里面的改动。这种形式每每在 GitHub 上以开源的形式进行协做。
对于一些更为复杂的项目来说,像 Linux 内核这样的开发工做流也是颇有效的。在这个模型中,负责人(lieutenants)负责整个项目的一些特定的子系统,他们合并全部跟那个子系统关联的变更。另一个维护者(dictator,字面理解:独裁者)只能从他管辖的负责人这里获取变动,并将这些变动推送到主要仓库。而后全部人都从这个仓库获取更新。
Git 的数据模型确保了项目内的每个字节,每个 bit 的一致性。提交的每个文件都会使用校验和计算摘要,检出的时候也使用这个摘要值。没有任何可能会出现从仓库中获取的内容跟你存储的内容有任何差别。
在不改变 ID(校验和)的状况下也不可能出现改变任何文件,日期,提交说明或者任何其余在 Git 仓库中的数据。这就意味着,若是你有一个 commit ID,你不但能够肯定这个版本的代码跟他提交的时候是如出一辙的,并且这个版本以前的历史也没有发生任何改变。
大多数中央存储的版本控制系统默认不提供这样的校验整合。
不像其余系统, Git 有一个概念叫作 “暂存区域” 或者 “index”。这是一个在提交执行以前的临时的区域能够用来格式化和审阅改动内容的。
一个 Git 优于其余系统的功能是咱们能够快速的暂存一些改动的文件,在工做目录中只提交部分改动的文件,或者文件改动的部份内容,以及在提交的时候在命令行里列出改动的文件列表。
暂存区域容许你仅仅暂存部分的文件改动,在你意识到你忘了提交其中一个文件以前,对文件进行两个逻辑上不相关的修改的日子已经一去不复返了。如今你能够仅仅暂存你当前提交须要改动的文件,其余的改动在下次提交再暂存。这个特性能够扩展到对文件进行的任何更改。
固然,Git 也容许你忽略掉暂存区域这个过程,你能够轻松的在 commit 命令后面添加 '-a' 选项来直接将全部改动提交。Git 会自动帮你先暂存到暂存区域,再执行提交。
Git 是一个使用 GNU GPL2.0 协议的开源软件。Git 选择 GPLv2 来确保你能够自由的分享和改造自由软件,并且能确保使用它的任何用户都是自由免费的。
然而,咱们确实也保留了 “Git” 和 logos 避免争议。欲知详情请看咱们的商标政策。
译者注
本文译自 Git 官方网站的关于说明