分支和合并

Git 跟其他版本控制系统最大的优势就在于其高级的分支模型。

Git 允许而且 鼓励 你在本地使用多个完全独立的分支。这些分支的创建,合并和删除几乎都可以在几秒内完成。

这意味着你可以轻松的做如下操作:

  • 无痛的上下文切换 创建分支试验一个想法,提交几次,切回你原来分支的状态,应用一个改动 patch,切回你原来正在试验的状态,将刚才应用的 patch 合并过来。
  • 基于角色的代码支线 你可能会有一个分支仅仅包含那些只存在于生产环境上的代码,另外有一个独立的分支用以合并测试环境代码,还有若干个更小一些的分支用于日常开发工作
  • 基于特性的工作流 为每一个新的特性创建新的分支,你可以方便平滑的在这些分支之间无缝切换,当这些特性的改动完成的时候,你可以将其合并入主分支,并把特性分支删掉。
  • 任意试验 创建一个分支专门用来试验,当觉得试验不理想的时候,直接删除掉即可,放弃掉之前的试验内容。这时候不会有任何其他人察觉到这个试验(甚至在这期间你还可以推送其他不相关的分支)

尤其是当你推送至远程仓库的时候,你不必推送所有分支,你可以选择只推送少数你愿意分享的分支,当然如果你愿意,也可以推送所有分支。这一点倾向于让开发者在试验很多新的想法的时候免除发布自己的未成熟的试验计划的顾虑。

当然,也有一些其他的系统可以部分实现上述的功能和优势,只是具体的执行会变的困难和容易出错。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 拥有分布式特性和极好的分支系统,你可以在此基础上轻松实现大量的工作流模型。

Subversion(SVN) 风格工作流

集中式存储的工作流非常常见,特别是对于那些从传统的集中式代码版本管理系统转过来使用 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 官方网站的关于说明

[译] 关于 Git 你需要知道的一些事情的更多相关文章

  1. [译]Atlassian Git系列教程

    国庆期间把Atlassian的Git系列教程看完了.边看边翻译了相关文章. 原教程: https://www.atlassian.com/git/tutorials/ 我翻译的: git init g ...

  2. [Git]自译《Git版本控制管理》——1.介绍(二)_Git诞生

    译者前言:      本系列译文为作者利用业余时间翻译,有些疏漏与翻译不到位的地方敬请谅解.      不过也很希望各位读者能给出中肯的建议.      方括号的注释,如[1][2]为译者注.     ...

  3. 如何在Git中撤销一切 | 干货

    翻译:李伟 审校:张帆 译自:Github JF杰微刊:如何在Git中撤销一切 任何一个版本控制系统中,最有用的特性之一莫过于 "撤销(undo)"操作.在Git中,"撤 ...

  4. 【转】如何在Git中撤销一切

    翻译:李伟 审校:张帆译自:Github 任何一个版本控制系统中,最有用的特性之一莫过于 “撤销(undo)”操作.在Git中,“撤销”有很多种含义. 当你完成了一次新的提交(commit),Git会 ...

  5. 在Git中如何撤销上一次的commit

    有的时候我们一不小心就git commit -m ‘commit message info’解决办法,很简单,只需执行git reset HEAD~这条命令即可,即能保证你原本的修改还在,也能撤销本次 ...

  6. SVN为什么比Git更好

    首先我表明一个根本的立场,我个人更喜欢用Git,但是,这仅仅是一个个人偏好.当我们需要将一种技术方案带给整个团队的时候,并不是由我们的个人偏好作为主要决定因素,而应该充分去权衡利弊,选择对团队,对公司 ...

  7. (转)git常见错误

    如果输入$ Git remote add origin git@github.com:djqiang(github帐号名)/gitdemo(项目名).git 提示出错信息:fatal: remote ...

  8. 学习git config配置文件

    设置 git status的颜色. git config --global color.status auto 一.Git已经在你的系统中了,你会做一些事情来客户化你的Git环境.你只需要做这些设置一 ...

  9. iOS学习之git的使用

    SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器.集中式版本控 ...

随机推荐

  1. Spring第一个例子的补充

    1.首先导入需要的包: 2.文件结构: 3.先看xml配置文件: <?xml version="1.0" encoding="UTF-8"?> &l ...

  2. python_json常用的方法

    1. 什么是JSON? JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端 ...

  3. C缺陷与陷阱----读书笔记---第一章

    第一章:词法陷阱 编译器中负责将程序分解为一个一个符号的部分,一般称为“词法分析器”.例如,对于语句: if ( x == big ) big = x ; 它的第一个符号是C语言关键字if,紧接着下一 ...

  4. ajax常用写法

    $.ajax( url,{ type:"post", data:{},}) .done(function() { alert("success"); }) .f ...

  5. 学习c++语言应该牢记的50条准则,同样学习其他语言也一样

    1.把C++当成一门新的语言学习(和C没啥关系!真的.): 2.看<Thinking In C++>,不要看<C++变成死相>: 3.看<The C++ Programm ...

  6. leetcode--001 max point on a line

    package leetcode; import java.util.HashMap; class Point{ int x; int y; Point(){ x=0; y=0; } Point(in ...

  7. 最基本的SQL语法/语句

    DDL—数据定义语言(Create,Alter,Drop,DECLARE) DML—数据操纵语言(Select,Delete,Update,Insert) DCL—数据控制语言(GRANT,REVOK ...

  8. sqlserver merge into

    create table #ttt(id int,name nvarchar(10));merge into #ttt t using (select 1 as id ,'eee' as name ) ...

  9. 安卓组件service

    [转]http://blog.csdn.net/ithomer/article/details/7364024 一. Service简介 Service是android 系统中的四大组件之一(Acti ...

  10. 为什么建立TCP连接需要三次握手,为什么断开TCP连接需要四次握手,TIME_WAIT状态的意义

    为什么建立TCP连接需要三次握手? 原因:为了应对网络中存在的延迟的重复数组的问题 例子: 假设client发起连接的连接请求报文段在网络中没有丢失,而是在某个网络节点长时间滞留了,导致延迟到达ser ...