<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>群英汇博客 &#187; 版本控制</title> <atom:link href="http://blog.ossxp.com/category/scm/feed/" rel="self" type="application/rss+xml" /><link>http://blog.ossxp.com</link> <description></description> <lastBuildDate>Wed, 14 Sep 2011 03:52:03 +0000</lastBuildDate> <generator>http://wordpress.org/?v=2.9.2</generator> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>Gist数据嵌入博客</title><link>http://blog.ossxp.com/2011/09/2521/</link> <comments>http://blog.ossxp.com/2011/09/2521/#comments</comments> <pubDate>Wed, 14 Sep 2011 03:50:57 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[版本控制]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2521</guid> <description><![CDATA[下面嵌入的Ruby代码，来自 gist.github.com访问 http://gotgit.github.com/gotgithub/ 阅读电子书《GotGitHub》。
]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/09/2521/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>版本库中一个大家都要改的文件，又不想每次提交而覆盖，怎么办？</title><link>http://blog.ossxp.com/2011/06/2507/</link> <comments>http://blog.ossxp.com/2011/06/2507/#comments</comments> <pubDate>Fri, 10 Jun 2011 09:05:24 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2507</guid> <description><![CDATA[一个朋友打来电话，问：“使用Git做版本控制，版本库中一个大家都要改的文件，又不想每次提交而覆盖，怎么办？”
我的手机信号不好，没有听明白到底是什么文件让他的团队/客户如此纠结。我估计是某个IDE软件的项目文件，没有不行，但是IDE工作的时候，这个文件会经常随着本地项目的改动而变化，而且和每个人项目部署的目录相关，因此不同的人这个文件并不一致。我曾经还是一个Windows开发人员的时候，在 VisualStudio 6.0（maybe）中遇到。
我跟他说两个解决方案，一个比较诡异一点，一个比较普世一点。先说第一个正常人不会想到的方案——稀疏检出
Git实际上是靠暂存区来跟踪工作区文件的改动，如果希望本地修改的工作区中文件（已经在版本库中），不被识别出被改动，也不能被添加和提交，Git是有办法实现的：为暂存区中文件设置“SparseCheckout”标志位即可。
例如对于一个示例版本库，工作区有四个文件，执行下面的命令，可以看出每个文件前面的标记字母 H。
$ git ls-files -v
H hello.c
H hello.h
H myproject.dsp
H myproject.dsw
文件前面标记的字母H，表明暂存区中的文件和工作区文件建立跟踪，是默认状态。什么命令可以更改这个状态呢？或者用稀疏检出的配置文件（.git/info/sparse-checkout) 或者用 git-update-index 命令。
$ git update-index --skip-worktree myproject.dsw$ git ls-files -v
H hello.c
H hello.h
H myproject.dsp
S myproject.dsw
看到了么，执行 git update-index 命令之后，文件 myproject.dsw 在命令 git ls-files -v 的输出结果中最前面的标识由 H 变成了 S。字母 S 的含义是暂存区不再和本地文件建立跟踪，进而忽略本地文件改动。
如果对 myproject.dsw 进行改动，执行 git status 命令会发现文件的改动被忽略，也无法提交。
$ echo  test &#62; myproject.dsw
$ git status -s
$ git add myproject.dsw
$ <a
href="http://blog.ossxp.com/2011/06/2507/" class="more-link">阅读全部内容 &#187;</a>]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/06/2507/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>Git版本库同步对部分版本库禁用</title><link>http://blog.ossxp.com/2011/06/2502/</link> <comments>http://blog.ossxp.com/2011/06/2502/#comments</comments> <pubDate>Thu, 02 Jun 2011 02:59:00 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[Gitolite]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2502</guid> <description><![CDATA[使用 Gitolite 假设 Git 服务，可以比较容易的配置服务器的冗余备份，在即将出版的《Git权威指南》，以及之前写的一个文档： http://www.ossxp.com/doc/git/gitolite.html 都可以看到。
当配置了Gitolite 服务器镜像之后，服务器中任何版本库的创建和推送操作都会同步写到另外的镜像服务器中，但有时会有针对个别版本库禁止镜像的需要。某些版本库保存一些二进制软件包之类非源码类文件，版本库太大，同步影响带宽。
个人版本库内容各异，做镜像没有必要。下面就介绍改造 Gitolite ，实现同步可定制的需求。使用gitolite.mirror 配置变量禁用版本库同步
修改了 gitolite 的 post-receive.mirrorpush 脚本，增加条件判断，对于配置变量 gitolite.mirror 设置为 false 的版本库，停止版本库同步。
$ git --git-dir=/path/to/repos.git config gitolite.mirror false
新建版本库自动设置 gitolite.mirror 配置变量
例如希望在 local 目录下创建的版本库，不进行镜像。即形如 local/repos1.git 的版本，只在本地服务器中存在，而不向远程服务器镜像。
可以利用 gitolite 配置文件中的 config 指令，对新建的版本库设置 gitolite.mirror 设置：
配置文件 gitolite-admin/conf/gitolite.conf 中相关配置：
repo local/.*$
C = @admin
RW+ = @admin
<a
href="http://blog.ossxp.com/2011/06/2502/" class="more-link">阅读全部内容 &#187;</a>]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/06/2502/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>《Git权威指南》官方网站上线</title><link>http://blog.ossxp.com/2011/05/2499/</link> <comments>http://blog.ossxp.com/2011/05/2499/#comments</comments> <pubDate>Fri, 20 May 2011 10:10:57 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[新闻]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2499</guid> <description><![CDATA[《Git权威指南》已于6月底出版，各大书店和网上书店有售，具体参见官网相关链接。
官方网站地址：http://www.ossxp.com/doc/gotgit/
这个网站是用 Git 维护的，人人皆可参与的哦。
]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/05/2499/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Repo 新增 hack：URL 自动 DotGit 后缀控制等</title><link>http://blog.ossxp.com/2011/04/2464/</link> <comments>http://blog.ossxp.com/2011/04/2464/#comments</comments> <pubDate>Tue, 19 Apr 2011 11:15:35 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[版本控制]]></category> <category><![CDATA[repo]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2464</guid> <description><![CDATA[在《Git权威指南》书中提到的 Repo 的 Hack 主要是增加了两条新的子命令，实现脱离 Gerrit 服务器直接向 Git 服务器提交。即：子命令 repo config 用于在清单库（Manifest）设置配置变量。
例如设置 repo.pushurl 配置变量，以便在直接向服务器推送时使用该地址（实际上还要在该地址后面添加版本库名称和 .git 后缀）。
子命令 repo push 用于绕过 Gerrit 服务器，直接向 Git 服务器推送。
该命令要参考清单库的 repo.pushurl 配置变量。最近的使用过程中，又发现有改进的必要，于是做了如下新的开发：
版本库URL自动DotGit后缀控制
发现 FreeMind 在 SourceForge 上的版本库地址不能在地址的后面出现 &#8220;.git&#8221; 后缀后，必须对 Repo 进行改造，否则无法使用 Repo 克隆不带 &#8220;.git&#8221; 后缀的 Git 版本库。
新增的 Hack 见 repo@github//ossxp-com上的 这个提交。改进后的 Repo 会读取清单库中 XML 文件的 remote 元素中的 autodotgit 属性，如果该属性设置为 &#8220;false&#8221; ，则不会在构建 URL 时添加 <a
href="http://blog.ossxp.com/2011/04/2464/" class="more-link">阅读全部内容 &#187;</a>]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/04/2464/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>用 repo 管理 Freemind 代码补丁</title><link>http://blog.ossxp.com/2011/04/2429/</link> <comments>http://blog.ossxp.com/2011/04/2429/#comments</comments> <pubDate>Fri, 08 Apr 2011 13:21:07 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[FreeMind]]></category> <category><![CDATA[repo]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2429</guid> <description><![CDATA[FreeMind 是我几乎每天都会用到的软件，虽说脑图软件不少，但 FreeMind 的文件是纯文本、可版本控制，所以一直是我的最爱。当然为了能更好的进行版本控制，还需要做些改进，就是我在 SourceForge 上建立的 FreeMind-MMX 项目。
最近发现 FreeMind 的代码库由 CVS 迁移到了 Git，这下访问官方代码库可方便多了。但是转换的并非尽善尽美，参见我新浪微博的评论。
之前把我的改进代码连同 FreeMind 代码一并放在公司的代码库中（用Topgit特性分支），如果迁移到新的 FreeMInd 代码库，再放到 Github 上，不知道又要占用多少宝贵的 Github 托管空间。灵机一动，为什么不用 repo —— 由 Andorid 项目引入的多 Git 版本库管理工具？
使用 repo 之后，我在 Github上Freemind 相关版本库占用甚至不到1M！官方版本库地址： git://freemind.git.sourceforge.net/gitroot/freemind/freemind
注意不能有 &#8220;.git&#8221; 后缀，如果添加后缀则无法克隆。
Github 上 FreeMind-MMX 的 Manifest 库的网址： https://github.com/ossxp-com/freemind-manifest
Github 上 FreeMind-MMX 的 代码补丁： https://github.com/ossxp-com/freemind-hacks自己动手编译改进后的 FreeMind，即 FreeMind-MMX 的方法：使用我改进的 repo，原因见微博上留言。
$ mkdir workspace
$ cd workspace
$ sudo <a
href="http://blog.ossxp.com/2011/04/2429/" class="more-link">阅读全部内容 &#187;</a>]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/04/2429/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Topgit 安装</title><link>http://blog.ossxp.com/2011/03/2392/</link> <comments>http://blog.ossxp.com/2011/03/2392/#comments</comments> <pubDate>Thu, 10 Mar 2011 12:23:59 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[版本控制]]></category> <category><![CDATA[topgit]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2392</guid> <description><![CDATA[Topgit 用 shell 脚本语言开发，可以安装在所有类Unix环境中，例如 Linux、Mac OS X[1] ，以及Windows下的Cygwin、msysGit等。下面的官方网站链接介绍了Topgit的安装和使用方法：http://repo.or.cz/w/topgit.git?a=blob;f=README 。1.    Linux下安装Topgit
安装官方的 Topgit 版本，直接克隆官方的版本库，执行 make 即可：
$ git clone git://repo.or.cz/topgit.git
$ cd topgit
$ make
$ make install
默认会把可执行文件 tg 安装在 $HOME/bin （用户主目录下的 bin 目录）下，如果没有将 ~/bin 加入环境变量 $PATH 中，可能无法执行 tg。
如果具有 root 权限，也可以在编译和安装时向make命令传递prefix环境变量，将 tg 安装在系统目录中。
$ make prefix=/usr
$ sudo make prefix=/usr install
我对 Topgit 做了一些增强和改进，在后面的章节将予以介绍。如果想安装改进的版本，需要预先安装 quilt 补丁管理工具，然后进行如下操作。
$ git clone git://github.com/ossxp-com/topgit.git
$ cd topgit
$ QUILT_PATCHES=debian/patches quilt push <a
href="http://blog.ossxp.com/2011/03/2392/" class="more-link">阅读全部内容 &#187;</a>]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/03/2392/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>《GotGit》附录D Git 和 Hg 面对面</title><link>http://blog.ossxp.com/2011/03/2370/</link> <comments>http://blog.ossxp.com/2011/03/2370/#comments</comments> <pubDate>Thu, 10 Mar 2011 01:03:16 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[版本控制]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2370</guid> <description><![CDATA[附录D   Git 和 Hg 面对面D.1   面对面访谈录
Git：你好 Hg，我发现我们真的很像。
Hg：是啊，人们把我们都归类为分布式版本控制工具，所以我们之间的相似度，要比和 CVS、SVN 的相似度高得多了。
Hg：我是用 Python 和少部分的 C 语言实现的，你呢？
Git：我的核心当然是使用 C 语言了，因为 Linus Torvalds 最爱用 C 语言了。我的很多命令还使用了 Shell 脚本和 Perl 语言开发，Python 用的很少。
Hg：大量的使用 C 语言，是你的性能比我高的原因么？
Git：当然不是了，你不也在核心模块使用 C  语言了么？问题的关键在于我的对象库设计的非常优秀。你不要忘了我是谁发明的，可是大名鼎鼎的 Linux 之父 Linus Tolvars，他对  Linux 文件系统可是再熟悉不过的了，所以他能够以文件系统开发者的视角实现我的核心。
Git：还有我的网络传输过程非常直观，可以显示实时的进度，好像我从你那里没有看到。之所以我能够有这样的实现，是因为我使用了“智能协议”。在网络传输的两端都启用了相应的辅助程序，实现差异传输及传输进度的计算和显示。
Hg：是啊，非常的惭愧。当克隆一个比较大的 Hg 版本库时，会出现假死状态，用户不知道克隆操作的进展。（感谢来自台湾的 Willie Wu，指出我的错误）
Hg：实际上我也支持进度显示，不过是通过Progress插件实现的，需要通过修改配置文件启用该插件。
Hg：我有一个特点是 SVN 用户非常喜欢的，就是我的顺序数字版本号。
Git：你的顺序数字版本号只在本地版本库中有效。也就是说，你不能像 SVN 那样将顺序数字版本号作为项目本身的版本号，因为换成另外一个版本库的克隆，那个数字版本号就会不一样了。
Hg：我觉得你的暂存区（stage）的概念太古怪了。我提交的时候，改动的文件会直接提交而不需要什么注册到暂存区的操作。
Git：让读者来作评判吧。如果读者读过本书的第2篇，一定会说 Git 的暂存区帅呆了。
Hg：我只允许用户对最近的一次提交进行回滚撤销，而你（Git）怎么能允许用户撤销任意多次历史提交呢？那样安全么？
Git：这就是的我对象库和引用设计的强大之处，我可以使用 git reset 命令将工作分支进行任意的重置，丢弃任意多的历史。至于安全性，我的重置命令有一个保险，就是 reflog ，我随时可以参照 reflog 的记录来弥补错误的重置。
Hg：我们的 revert 命令好像不同？
Git：你 <a
href="http://blog.ossxp.com/2011/03/2370/" class="more-link">阅读全部内容 &#187;</a>]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/03/2370/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>《GotGit》附录C Git 和 SVN 面对面</title><link>http://blog.ossxp.com/2011/03/2368/</link> <comments>http://blog.ossxp.com/2011/03/2368/#comments</comments> <pubDate>Thu, 10 Mar 2011 01:02:54 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[版本控制]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2368</guid> <description><![CDATA[附录C   Git 和 SVN 面对面C.1   面对面访谈录
Git：我的提交历史本身就是一幅美丽的图画 —— DAG（Directed Acylic Graph, 有向非环图），可以看到各个分支之间的合并关系。而你 SVN，你的提交历史怎么是一条直线呢？要是在重症监护室看到你，还以为你挂掉了呢？
SVN：我觉得挺好，至少我每次提交会有一个全局的版本号，而且我的版本号是递增的。你的版本号不是递增的吧！
Git：你说的对，我的版本号不是一个简单递增的数字，而是一个长达40位的十六进制数字（哈希值），但是可以使用短格式，只要不 冲突。虽然我的提交编号看起来似乎是无序的，但实际上我每一个提交都记录了父提交甚至是双亲或多亲提交，因此可以很容易的从任意一个提交开始建立一条指向 历史提交的跟踪链。
SVN：是啊，我的一个提交和前一个提交有时根本没有关系，例如一个提交是发生在主线 /trunk 中的，下一个提交可能就发生在 /branches/1.3.x 分支中。你要知道要想画出一个像你那样的分支图，我要做多少工作么？我不容易呀。
Git：我一直很奇怪，你的分支和里程碑怎么看起来和目录一样？我的分支和里程碑名字虽然看起来像是目录，实际上和工作区的目录完全没有关系，只是对提交ID的一个记号而已。
SVN：我一开始觉得我用轻量级拷贝的方式实现分支和里程碑会很酷，也很快。但是我发现很多人在使用我的时候，直接在版本库的根目录下创建文件而不是把文件创建在 /trunk 目录下，这就导致这些人无法再创建分支和里程碑了，因为是无法将根目录拷贝到子目录的呀！
Git：那么你是如何对分支合并进行跟踪的呢？我因为有了 DAG 的提交关系图，是很容易看出来分支之间的合并历史，但是你是怎么做到的呢？
SVN：我用了一点小技巧，就是通过属性（svn:mergeinfo）记录了合并的分支名和版本范围，这样再合并的时候，我会根据相关属性确定是否要合并。但是如果经常在子目录下合并，有太多的 svn:mergeinfo 属性等待我检查，我会很困扰。还有我的这个功能是在 1.5 以后版本才提供的，因此老版本会破坏这个机制。
SVN：对了，我的属性能干很多事哦，我甚至可以把我的照片作为属性附加在文件上。
Git：这点我承认，你的属性非常强大。其实我也支持属性，只不过实现方式不同罢了。而且我可以通过评注的方式为任意对象（提交、文件、里程碑等）添加评注，也可以实现把照片做为评注附加在文件上，可是这个功能有什么实际用处么？
SVN：我有轻量级拷贝，而我的分支和里程碑就是通过拷贝实现的，很强大哦。
Git：我根本就不需要轻量级拷贝，因为我对文件的保存是和文件路径无关的，我只关心内容。所以相同内容的文件无论它们的文件名相差有多大，在我这里只保存一份。而你 SVN，如果用户忘了用轻量级拷贝，版本库是不是负担很重啊。
SVN：听说你不能针对目录授权，这可是我的强项，所以公司无论大小都在用我作为版本控制系统。
Git：不要说你的授权了，简直是一团糟。虽然这本书的作者为你写了一个图形化的授权管理工具 （http://www.ossxp.com/doc/pysvnmanager/user-guide/user-guide.html）会有所改善， 但是你糟糕的分支和里程碑的实现，会导致授权在新的分支和里程碑中要一一设置，工作量其大无比。虽然泛路径授权是一个解决方案，但是官方并没有提供啊。
Git：说说我的授权吧。如果你认真的读过本书服务器架设的相关章节，你会为我能够提供的按照分支，以及按照路径进行写操作授权而 击掌叫好的。当然我的读操作授权还不能做到很精细，但是可以将版本库拆分成若干小的版本库啊，再用参照本书介绍的各种多版本库协同模式，会找到一个适合的 解决方案的啊。
Git：我的工作区很干净。只在工作区的根目录下有一个 .git 目录，此外再无其他。
SVN：我要在工作区的每一个目录下都放置一个 .svn 目录，这个目录在 Linux 下可是隐藏的哦。这个目录下不但有跟踪工作区文件状态的跟踪文件，而且还有每一个文件的原始拷贝呢。这样有的操作就可以脱离网络执行了，例如：差异比较，工作区文件的回滚。
Git：嗯，你要是像我一样再保存多一点内容（整个版本库）就更好了。像你这样在每个工作区子目录下都有一个 .svn  目录，而且每个 .svn 目录下都有文件原始拷贝，在进行内容搜索的时候会搜索出来两份吧，太干扰了。而且你这么做和 CVS  一样有安全风险，造成本地文件名的信息泄漏，千万不要在 Web 服务器上用 SVN 检出哦。
Git：我的操作可以不需要网络。因为我在本地拥有完整的版本库，几乎所有操作都是在本地完成。
SVN：正如前面说到的，我有部分命令可以不需要网络，但是其他绝大多数命令还是要依赖网络的。
CVS：你怎么没有更新（update）命令？还有你为什么老是要执行检出命令（checkout）？对我而言，检出命令只在工作区创建时一次完成的。
Git：你的这个问题怎么和 CVS 问的一样。你的更新（update）命令执行的很慢对么？首先你要用检出命令（checkout）建立工作区，然后你要经常的执行更新（update）命令进行更新，否则容易造成你的更改和他人更改发生冲突。
Git：之所以你需要更新是因为你的版本库在远程啊。别忘了我的版本库是在本地，我的每一步操作工作区和版本库都是同步的，所以更 新操作就没有存在的必要了。而我的检出（checkout）操作一般是用户切换分支，或者从本地版本库检出丢失的文件或覆盖本地错误改动的文件时用到。如 果我没记错的话，你切换分支用的是 svn switch 命令对么？
Git：实际上我也有一个比较耗时的网络操作命令叫做 <a
href="http://blog.ossxp.com/2011/03/2368/" class="more-link">阅读全部内容 &#187;</a>]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/03/2368/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>《GotGit》附录B Git 与 CVS 面对面</title><link>http://blog.ossxp.com/2011/03/2365/</link> <comments>http://blog.ossxp.com/2011/03/2365/#comments</comments> <pubDate>Thu, 10 Mar 2011 01:01:32 +0000</pubDate> <dc:creator>蒋 鑫</dc:creator> <category><![CDATA[Git]]></category> <category><![CDATA[版本控制]]></category> <category><![CDATA[《Got Git》]]></category><guid
isPermaLink="false">http://blog.ossxp.com/?p=2365</guid> <description><![CDATA[附录B  Git 与 CVS 面对面B.1   面对面访谈录
Git：我的提交是原子提交。每次提交都对应于一个目录树（树对象）。因为我的提交ID是对目录树及相关的提交信息建立的一个SHA1哈希值，所以可以保证数据的完整性。
CVS：我承认这是我的软肋，一次错误或冲突的提交会导致部分数据被提交，而部分数据没有提交，版本库完整性被破坏，所以人们才设计出来 Subversion（SVN） 来取代我。
Git：我的分支和里程碑管理非常快捷。因为我的分支和里程碑就是一个记录提交ID的引用，你的呢？
CVS：你怎么又提到别人的痛处了！我的分支和里程碑创建速度还是很快的，&#8230;嗯&#8230; ， 如果在版本库中只有几个文件的话。当然如果版本库的文件的很多，创建分支、里程碑创建就需要花费更多的时间。有些人对此忍无可忍，于是设计出 SVN 来取代我。
Git：其实我不用里程碑都没有关系，因为每一个提交ID就对应于唯一的一个提交状态。
CVS：这也是我做不到的。我没有全局版本号的概念，每一个文件都通过单独的版本号记录其变更历史，所以人们在使用我的时候必须经常地用里程碑 （tag）对我的状态进行标识。还需要提醒一句，如果版本库中文件太多，创建里程碑是很耗时的，因为要一一打开每一个版本库中的文件，在其中记录里程碑和 文件版本的关系。
Git：我的工作区很干净。只在工作区的根目录下有一个 .git 目录，此外再无其他辅助目录或文件。
CVS：我要在工作区的每一个目录下都放置一个 CVS 目录，这个目录下有个 Entries 文件很重要，记录了对应工作区文件的检出版本以及时间戳等信息。这样做的好处是可以将工作区移动到任何其他磁盘和目录，依然可以使用，甚至我可以将工作区的一个子目录拿出来，作为独立的工作区。
Git：我也可以将工作区移动到其他磁盘，但是要保证工作区下的 .git 目录和工作区一同移动。也不可以只移动工作区下的一个目录到其他磁盘或目录，那样的话移出的目录就不能工作了。
Git：我的网络传输效率很高。在和其他版本库交互时，对方会告诉我他有什么，我也知道我有什么，因为只对缺失对象的打包传输，所以效率很高而且能够显示传输进度。
CVS：这一点我不行。因为我本地没有文件做对照，所以我在传输的时候不可能做到增量传输。
Git：我甚至可以不需要网络，因为我在本地拥有完整的版本库，几乎所有操作都是在本地完成。
CVS：我的操作处处需要网络，如果版本库是在网络中其他服务器上的话。如果网速比较慢，查看日志、查看历史版本都需要花费很长时间等待。
CVS：你怎么没有更新（update）命令？还有你为什么老是要执行检出命令（checkout）？对我而言，检出命令只在工作区创建时一次完成的。
Git：你的检出命令（checkout）是从远程版本库服务器获取数据完成本地工作区的创建，版本库仍然位于远程的服务器上。你 的更新（update）命令执行的很慢对么？之所以你需要执行更新命令是因为你的版本库在远程啊。别忘了我的版本库是在本地，我的每一步操作工作区和版本 库都是同步的，所以更新操作就没有存在的必要了。而我的检出（checkout）操作是将本地版本库的数据检出到本地工作区，用于恢复本地丢失的文件或错 误改动的文件，也用于切换不同的分支。我也有一个和你的更新（update）操作类似的比较耗时的网络操作命令叫做 git fetch 或 git  pull，这两个操作是从别人的版本库获取他人改动。一般使用我（Git）做团队协作的时候，会部署一个集中共享的版本库，我就用这两个命令（git  fetch 或 git pull）从共享的版本库执行拉回操作。也也许你（CVS）会觉得 git fetch 或者 git pull 和你的  cvs update 命令更像吧。至于你的检出命令（cvs checkout），实际上和我克隆命令（git  clone）很相似，只不过我的克隆命令不但创建了本地工作区，而且在本地还复制了和远程版本库一样的本地版本库。
CVS：为什么你的检入命令（commit）命令执行的那么快？
Git：是的，我的检入命令飞一般就执行完了，也是因为版本库就在本地。也许你（CVS）会觉得我的推送命令（git  push）和你的检入命令（cvs commit）更相像，其实这是一个误会。如果我不做本地提交，是不能通过推送命令（git  push）将我的本地的提交共享给（推送给）其他版本库的。你（CVS）每一次提交都要和版本库进行网络通讯，而我可以在本地版本库进行多次提交，直到我 的主人想喝咖啡了才执行一次 git <a
href="http://blog.ossxp.com/2011/03/2365/" class="more-link">阅读全部内容 &#187;</a>]]></description> <wfw:commentRss>http://blog.ossxp.com/2011/03/2365/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (user agent is rejected)
Database Caching using disk

Served from: blog.ossxp.com @ 2012-02-09 17:03:54 -->
