一段时间以来,我一直在我的个人项目中使用subversion。

我听到越来越多关于Git、Mercurial和DVCS的好消息。

我想尝试一下DVCS,但我对这两种选择都不太熟悉。

Mercurial和Git之间有什么区别?

注意:我并不是要找出哪一个是“最好的”,或者我应该从哪一个开始。我主要寻找它们相似和不同的关键领域,因为我想知道它们在实现和理念方面有何不同。


当前回答

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

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

然而,Git和Mercurial之间也存在显著的差异,这使得它们都更适合于自己的用例子集。

Mercurial比较容易学习。在使用Mercurial几周后,我几乎不需要参考文档或笔记;即使在使用Git一年之后,我仍然需要定期查阅我的笔记。Git要复杂得多。

This is partly because Mercurial is just plain cleaner. You rarely have to branch manually in Mercurial; Mercurial will create an anonymous branch automatically for you if and when you need it. Mercurial nomenclature is more intuitive; you don't have to worry about the difference between "fetch" and "pull" as you do with Git. Mercurial is a bit less buggy. There are file name case sensitivity issues that used to cause problems when pushing projects across platforms with both Git and Mercurial; this were fixed in Mercurial some time ago while they hadn't been fixed in Git last I checked. You can tell Mercurial about file renames; with Git, if it doesn't detect the rename automatically - a very hit or miss proposition in my experience - the rename can't be tracked at all.

The other reason for Git's additional complication, however, is that much of it is needed to support additional features and power. Yes, it's more complicated to handle branching in Git - but on the other hand, once you have the branches, it's not too difficult to do things with those branches that are virtually impossible in Mercurial. Rebasing branches is one of these things: you can move your branch so that its base, instead of being the state of the trunk when you branched, is the state of the trunk now; this greatly simplifies version history when there are many people working on the same code base, since each of the pushes to trunk can be made to appear sequential, rather than intertwined. Similarly, it's much easier to collapse multiple commits on your branch into a single commit, which can again help in keeping the version control history clean: ideally, all the work on a feature can appear as a single commit in trunk, replacing all the minor commits and subbranches that the developer may have made while developing the feature.

Ultimately I think the choice between Mercurial and Git should depend on how large your version control projects are, measured in terms of the number of people working on them simultaneously. If you have a group of a dozen or more working on a single monolithic web application, for example, Git's more powerful branch management tools will make it a much better fit for your project. On the other hand, if your team is developing a heterogeneous distributed system, with only one or two developers working on any one component at any one time, using a Mercurial repository for each of the component projects will allow development to proceed more smoothly with less repository management overhead.

底线:如果你有一个庞大的团队在开发一个庞大的应用程序,那就使用Git;如果您的单个应用程序很小,任何规模都来自于这些应用程序的数量而不是大小,请使用Mercurial。

其他回答

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

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

我想你们可以通过这两个视频了解这些系统的相似或不同之处:

Linus Torvalds谈Git (http://www.youtube.com/watch?v=4XpnKHJAok8) 布莱恩·奥沙利文谈Mercurial (http://www.youtube.com/watch?v=JExtkqzEoHY)

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

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

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

Git作为SVN的厚客户端比Mercurial更好。可以对SVN服务器进行拉推操作。这个功能在Mercurial中仍处于开发阶段

Mercurial和Git都有非常好的网络托管解决方案(BitBucket和GitHub),但谷歌代码只支持Mercurial。顺便说一下,他们对Mercurial和Git进行了非常详细的比较,以决定支持哪一个(http://code.google.com/p/support/wiki/DVCSAnalysis)。它有很多好的信息。

看看Scott Chacon不久前的帖子。

我认为git以“更复杂”而闻名,尽管在我的经验中,它并没有比它需要的更复杂。在我看来,git模型更容易理解(标签包含提交(以及指向零个或多个父提交的指针)包含树,包含blob和其他树…完成)。

git并不比mercurial更令人困惑,这不仅仅是我的经验。我建议你再读一遍Scott Chacon关于这个问题的博文。

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

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

然而,Git和Mercurial之间也存在显著的差异,这使得它们都更适合于自己的用例子集。

Mercurial比较容易学习。在使用Mercurial几周后,我几乎不需要参考文档或笔记;即使在使用Git一年之后,我仍然需要定期查阅我的笔记。Git要复杂得多。

This is partly because Mercurial is just plain cleaner. You rarely have to branch manually in Mercurial; Mercurial will create an anonymous branch automatically for you if and when you need it. Mercurial nomenclature is more intuitive; you don't have to worry about the difference between "fetch" and "pull" as you do with Git. Mercurial is a bit less buggy. There are file name case sensitivity issues that used to cause problems when pushing projects across platforms with both Git and Mercurial; this were fixed in Mercurial some time ago while they hadn't been fixed in Git last I checked. You can tell Mercurial about file renames; with Git, if it doesn't detect the rename automatically - a very hit or miss proposition in my experience - the rename can't be tracked at all.

The other reason for Git's additional complication, however, is that much of it is needed to support additional features and power. Yes, it's more complicated to handle branching in Git - but on the other hand, once you have the branches, it's not too difficult to do things with those branches that are virtually impossible in Mercurial. Rebasing branches is one of these things: you can move your branch so that its base, instead of being the state of the trunk when you branched, is the state of the trunk now; this greatly simplifies version history when there are many people working on the same code base, since each of the pushes to trunk can be made to appear sequential, rather than intertwined. Similarly, it's much easier to collapse multiple commits on your branch into a single commit, which can again help in keeping the version control history clean: ideally, all the work on a feature can appear as a single commit in trunk, replacing all the minor commits and subbranches that the developer may have made while developing the feature.

Ultimately I think the choice between Mercurial and Git should depend on how large your version control projects are, measured in terms of the number of people working on them simultaneously. If you have a group of a dozen or more working on a single monolithic web application, for example, Git's more powerful branch management tools will make it a much better fit for your project. On the other hand, if your team is developing a heterogeneous distributed system, with only one or two developers working on any one component at any one time, using a Mercurial repository for each of the component projects will allow development to proceed more smoothly with less repository management overhead.

底线:如果你有一个庞大的团队在开发一个庞大的应用程序,那就使用Git;如果您的单个应用程序很小,任何规模都来自于这些应用程序的数量而不是大小,请使用Mercurial。

I use both quite regularly. The major functional difference is in the way Git and Mercurial name branches within repositories. With Mercurial, branch names are cloned and pulled along with their changesets. When you add changes to a new branch in Mercurial and push to another repository, the branch name is pushed at the same time. So, branch names are more-or-less global in Mercurial, and you have to use the Bookmark extension to have local-only lightweight names (if you want them; Mercurial, by default, uses anonymous lightweight codelines, which in its terminology are called "heads"). In Git, branch names and their injective mapping to remote branches are stored locally and you must manage them explicitly, which means knowing how to do that. This is pretty much where Git gets its reputation for being harder to learn and use than Mercurial.

正如其他人在这里注意到的,有很多很多微小的差异。分支是一个很大的微分器。