Git和Mercurial - 比较和对比

时间:2009-10-21 04:46:36

标签: git version-control mercurial dvcs

有一段时间我一直在为我的个人项目使用subversion。

我越来越多地听到关于Git和Mercurial以及DVCS的一般情况。

我想给整个DVCS带来一些旋转,但我对这两种选择都不太熟悉。

Mercurial和Git之间有什么区别?

注意:我试图找出哪一个是“最好的”,或者哪个是我应该开始的。我主要是寻找他们相似的关键领域,以及他们不同的地方,因为我很想知道他们在实施和理念方面的差异。

11 个答案:

答案 0 :(得分:446)

答案 1 :(得分:56)

我认为通过对这两个视频进行评分,您可以了解这些系统的相似或不同之处:

Linus Torvalds on Git(http://www.youtube.com/watch?v=4XpnKHJAok8
Mercurial的Bryan O'Sullivan(http://www.youtube.com/watch?v=JExtkqzEoHY

它们在设计上非常相似,但在实现方面却大不相同。

我使用Mercurial。据我了解Git,git的一个主要不同之处在于它跟踪文件的内容而不是文件本身。 Linus说,如果你将一个函数从一个文件移动到另一个文件,Git会告诉你整个移动过程中单个函数的历史。

他们还说git比HTTP慢,但它拥有自己的网络协议和服务器。

Git作为SVN胖客户端比Mercurial更好。您可以拉动和推送SVN服务器。 Mercurial

中仍在开发此功能

Mercurial和Git都有非常好的网络托管解决方案(BitBucket和GitHub),但Google Code仅支持Mercurial。顺便说一句,他们对Mercurial和Git做了非常详细的比较,他们决定支持哪一个(http://code.google.com/p/support/wiki/DVCSAnalysis)。它有很多好消息。

答案 2 :(得分:30)

我刚刚写了一篇关于Mercurial分支模型的博客文章,并将其与git的分支模型进行了比较。也许你会发现它很有趣:http://stevelosh.com/blog/entry/2009/8/30/a-guide-to-branching-in-mercurial/

答案 3 :(得分:25)

我经常使用它们。主要的功能差异在于Git和Mercurial在存储库中的名称分支。使用Mercurial,可以克隆分支名称并将其与变更集一起拉出。将更改添加到Mercurial中的新分支并推送到另一个存储库时,将同时推送分支名称。因此,Mercurial中的分支名称或多或少是全局的,您必须使用Bookmark扩展名才能拥有仅限本地的轻量级名称(如果需要;默认情况下,Mercurial使用匿名轻量级代码行,其术语是被称为“头”)。在Git中,分支名称及其到远程分支的内射映射存储在本地,您必须明确地管理它们,这意味着知道如何做到这一点。这就是Git因为比Mercurial更难学习和使用而获得声誉的地方。

正如其他人会在这里指出的那样,存在很多很多细微差别。分支机构是最大的区别。

答案 4 :(得分:19)

看看Patrick Thomson撰写的Git vs. Mercurial: Please Relax博客文章,他写道: Git是MacGyver Mercurial是James Bond

请注意,此博客文章发布于2008年8月7日,自那时起SCM都有所改进。

答案 5 :(得分:11)

Mercurial几乎完全用python编写。 Git的核心是用C语言编写的(应该比Mercurial的更快)和用sh,perl,tcl编写的工具,并使用标准的GNU工具。因此,它需要将所有这些工具和解释器带到不包含它们的系统(例如Windows)。

两者都支持使用SVN,虽然AFAIK svn支持在Windows上被git打破(可能我只是不幸/跛,谁知道)。还有一些扩展可以在git和Mercurial之间进行互操作。

Mercurial很不错Visual Studio integration。我上次检查时,plugin for Git正在工作,但速度非常慢。

它们的基本命令集非常相似(init,clone,add,status,commit,push,pull等)。因此,基本工作流程将是相同的。此外,两者都有类似TortoiseSVN的客户端。

Mercurial的扩展可以用python编写(毫不奇怪!),对于git,它们可以用任何可执行的形式(可执行的二进制文件,shell脚本等)编写。有些扩展功能很强大,比如git bisect

答案 6 :(得分:11)

如果您需要良好的Windows支持,您可能更喜欢Mercurial。 TortoiseHg(Windows资源管理器插件)设法为一个相当复杂的工具提供一个简单易用的图形界面。如此处所示,您还将拥有Visual Studio plugin。但是,我上次尝试时,SVN界面在Windows上运行得不好。

如果你不介意命令行界面,我会推荐Git。不是出于技术原因,而是出于战略原因。 git的采用率远高。看看有多少着名的开源项目正在从cvs / svn切换到Mercurial,有多少正在转向Git。与Mercurial托管相比,查看使用git支持可以找到多少代码/项目托管服务提供商。

答案 7 :(得分:11)

在阅读完全表明Mercurial更容易之后(我仍然认为,毕竟互联网社区的意见),当我开始使用Git和Mercurial时,我觉得Git对我来说相对简单(我从命令行开始使用Mercurial和TortoiseHg),主要是因为git命令根据我的命名而且数量较少。 Mercurial对每个执行不同命令的命令都有不同的命名作业,而Git命令可以根据情况多用途(例如,checkout)。虽然当时Git更难,但现在差距并不大。 YMMV ..有了像TortoiseHg这样的优秀GUI客户端,真的很容易使用Mercurial而且我不必记住稍微混乱的命令。我不会详细说明同一行为的每个命令如何变化,但这里有两个全面的列表:1 from Mercurial's own site2nd from wikivs

╔═════════════════════════════╦════════════════════════════════════════════════════════════════════════════════════════════════╗
║           Git               ║                Mercurial                                                                       ║
╠═════════════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════╣
║ git pull                    ║ hg pull -u                                                                                     ║
║ git fetch                   ║ hg pull                                                                                        ║
║ git reset --hard            ║ hg up -C                                                                                       ║
║ git revert <commit>         ║ hg backout <cset>                                                                              ║
║ git add <new_file>          ║ hg add <new_file> (Only equivalent when <new_file> is not tracked.)                            ║
║ git add <file>              ║ Not necessary in Mercurial.                                                                    ║
║ git add -i                  ║ hg record                                                                                      ║
║ git commit -a               ║ hg commit                                                                                      ║
║ git commit --amend          ║ hg commit --amend                                                                              ║
║ git blame                   ║ hg blame or hg annotate                                                                        ║
║ git blame -C                ║ (closest equivalent): hg grep --all                                                            ║
║ git bisect                  ║ hg bisect                                                                                      ║
║ git rebase --interactive    ║ hg histedit <base cset> (Requires the HisteditExtension.)                                      ║
║ git stash                   ║ hg shelve (Requires the ShelveExtension or the AtticExtension.)                                ║
║ git merge                   ║ hg merge                                                                                       ║
║ git cherry-pick <commit>    ║ hg graft <cset>                                                                                ║
║ git rebase <upstream>       ║ hg rebase -d <cset> (Requires the RebaseExtension.)                                            ║
║ git format-patch <commits>  ║ hg email -r <csets> (Requires the PatchbombExtension.)                                         ║
║   and git send-mail         ║                                                                                                ║
║ git am <mbox>               ║ hg mimport -m <mbox> (Requires the MboxExtension and the MqExtension. Imports patches to mq.)  ║
║ git checkout HEAD           ║ hg update                                                                                      ║
║ git log -n                  ║ hg log --limit n                                                                               ║
║ git push                    ║ hg push                                                                                        ║
╚═════════════════════════════╩════════════════════════════════════════════════════════════════════════════════════════════════╝

Git在内部保存了每个版本的已提交文件的记录,而Hg只保存了占用空间较小的变更集。与Hg相比,Git可以更容易地改变历史,但再一次是它的仇恨或爱情特征。我喜欢前者的Hg和后者的Git。

我在Hg中错过的是Git的子模块功能。 Hg有subrepos,但这不完全是Git子模块。

两者之间的生态系统也会影响一个人的选择:Git必须更受欢迎(但这是微不足道的),Git有GitHub而Mercurial有BitBucket,Mercurial有TortoiseHg,我没有看到对Git有好处。

每个都有其优点和缺点,其中任何一个都不会失去。

答案 8 :(得分:8)

不久前查看Scott Chacon's post

我认为git以“更复杂”而闻名,尽管根据我的经验,它并不比它需要的复杂。 IMO,git模型方式更容易理解(标签包含提交(指向零或更多父提交的指针)包含树包含blob和其他树...完成)。

不仅仅是我的经验,git并不比mercurial更令人困惑。我建议再次阅读this blog post from Scott Chacon

答案 9 :(得分:5)

我在目前的工作中使用Git一年多一点,在此之前,在我以前的工作中使用了Mercurial一年多一点。我将从用户的角度提供评估。

首先,两者都是分布式版本控制系统。分布式版本控制系统需要改变传统版本控制系统的思维方式,但一旦理解它们,实际上在许多方面都会更好地工作。出于这个原因,我认为Git和Mercurial都优于Subversion,Perforce等。分布式版本控制系统和传统版本控制系统之间的差异远大于Git和Mercurial之间的差异。

然而,Git和Mercurial之间也存在显着差异,使每个更适合其自己的用例子集。

Mercurial更容易学习。在使用Mercurial几周后,我很难提到文档或笔记;即使在使用它一年之后,我仍然需要定期使用Git来引用我的笔记。 Git要复杂得多。

这部分是因为Mercurial只是简单清洁。您很少需要在Mercurial中手动分支; Mercurial会在您需要时自动为您创建一个匿名分支。 Mercurial命名法更直观;你不必担心&#34; fetch&#34;之间的区别。并且&#34;拉&#34;就像你用Git一样。 Mercurial的马车少了一点。存在文件名区分大小写问题,这些问题在使用Git和Mercurial跨平台推送项目时会导致问题;这个问题在很久以前就已经在Mercurial修复了,而我们在最后检查时没有在Git中修复过。你可以告诉Mercurial文件重命名;使用Git,如果它没有自动检测到重命名 - 根据我的经验非常命中或错过命题 - 重命名根本无法跟踪。

然而,Git额外复杂性的另一个原因是需要大部分功能来支持其他功能和功能。是的,在Git中处理分支更复杂 - 但另一方面,一旦你拥有了分支,用Mercurial中几乎不可能的那些分支做事情并不困难。重新分支是这些事情之一:你可以移动你的分支,使它的基础,而不是你分支时的主干状态,现在是主干的状态;当有许多人在相同的代码库上工作时,这极大地简化了版本历史,因为每个推送到trunk可以看起来是顺序的,而不是交织在一起。同样,将分支上的多个提交折叠成单个提交会更容易,这可以再次帮助保持版本控制历史记录清洁:理想情况下,功能上的所有工作都可以在trunk中显示为单个提交,替换开发人员在开发该功能时可能进行的所有次要提交和子分支。

最终我认为Mercurial和Git之间的选择应取决于您的版本控制项目的大小,以同时处理它们的人数来衡量。例如,如果您有一个或多个团队在一个单一的Web应用程序上工作,那么Git的更强大的分支管理工具将使其更适合您的项目。另一方面,如果您的团队正在开发异构分布式系统,任何时候只有一个或两个开发人员在任何一个组件上工作,那么为每个组件项目使用Mercurial存储库将允许开发更顺利,更少存储库管理开销。

结论:如果你有一个大团队开发一个庞大的应用程序,请使用Git;如果您的个人应用程序很小,任何比例来自数字而不是此类应用程序的大小,请使用Mercurial。

答案 10 :(得分:4)

与DVCS本身完全无关的一个区别是:

Git似乎非常受C开发人员的欢迎。 Git是Linux内核的事实上的存储库,这可能是它为什么如此受C开发人员欢迎的原因。对于那些只能在Linux / Unix世界中工作的人来说尤其如此。

Java开发人员似乎更喜欢Mercurial而不是Git。可能有两个原因:一个是Mercurial上托管了许多非常大的Java项目,包括JDK本身。另一个是Mercurial的结构和干净的文档吸引了来自Java阵营的人,而这些人发现Git不一致wrt命令命名和缺乏文档。我并不是说这是真的,我说人们已经习惯了他们惯常居住的东西,然后他们倾向于从中选择DVCS。

我认为Python开发人员几乎完全支持Mercurial。除了Mercurial基于Python的事实之外,实际上没有合理的理由。 (我也使用Mercurial,我真的不明白为什么人们会对DVCS的实现语言大惊小怪。我不理解Python的一个词,如果它不是因为它被列在某个地方而已是基于Python然后我不会知道。

我认为你不能说一个DVCS比另一个更适合一种语言,所以你不应该选择那种。但实际上,人们(部分)选择他们最常接触的DVCS作为社区的一部分。

(不,我没有使用统计数据来支持我的上述声明......这都是基于我自己的主观性)