Mercurial和Git有什么区别?

我一直在使用git一段时间在Windows上(与msysGit),我喜欢分布式源代码pipe理的想法。 就在最近我一直在看Mercurial(汞),它看起来很有趣。 不过,我无法围绕着hg和git的区别。

有没有人在git和hg之间进行了比较? 我很有兴趣知道什么是不同的hg和git,而不必跳进fanboy讨论。

这些文章可能有助于:

  • Git与Mercurial:请放松 (Git是MacGyver,Mercurial是James Bond)
  • Mercurial和Git的区别

编辑 :比较Git和Mercurial名人似乎是一个趋势。 还有一个:

  • Git是Wesley Snipes,Mercurial是Denzel Washington

我在Mercurial上工作,但基本上我相信这两个系统是相同的。 他们都使用相同的抽象:构成历史的一系列快照(变更集)。 每个变更集知道它来自哪里(父变更集)并且可以有许多子变更集。 最近的hg-git扩展在Mercurial和Git之间提供了一个双向桥梁,并且显示了这一点。

Git着重于改变这个历史图表(带来所有的后果),而Mercurial并不鼓励历史重写, 但无论如何 , 这很容易做到 , 而且这样做的后果正是你应该期待的(这是,如果我修改了一个已经有的变更集,如果你从我那里得到的话,你的客户将会看到它是新的)。 所以Mercurial对非破坏性命令有偏见

至于轻量级的分支机构,Mercurial支持自多个分支机构以来,我总是这样想。 拥有多个分支的Git仓库正是这样的:在一个仓库中有多个不同的开发链。 Git然后添加名称到这些链,并允许您远程查询这些名称。 Mercurial的书签扩展添加了本地名称,在Mercurial 1.6中,您可以在推/拉时移动这些书签。

我使用Linux,但是显然TortoiseHg比Windows上的Git等价物更快,更好(由于较差的Windows文件系统的更好的使用)。 http://github.com和http://bitbucket.org提供在线托pipe,在Bitbucket的服务是伟大的和响应(我还没有尝试github)。;

我select了Mercurial,因为它感觉干净而优雅 – 我被Git的shell / Perl / Ruby脚本推迟了。 如果您想知道我的意思,请尝试查看git-instaweb.sh文件 :它是一个生成Ruby脚本的shell脚本,我认为它运行的是Web服务器。 shell脚本生成另一个shell脚本来启动第一个Ruby脚本。 还有一点Perl ,好的措施。

我喜欢将Mercurial和Git与James Bond和MacGyver进行比较的博文 – Mercurial比Git更低调。 在我看来,使用Mercurial的人并不那么容易被打动。 这体现在每个系统如何做Linus所说的“最酷的合并! 。 在Git中,您可以通过执行以下操作来与不相关的存储库合并:

 git fetch <project-to-union-merge> GIT_INDEX_FILE=.git/tmp-index git-read-tree FETCH_HEAD GIT_INDEX_FILE=.git/tmp-index git-checkout-cache -a -u git-update-cache --add -- (GIT_INDEX_FILE=.git/tmp-index git-ls-files) cp .git/FETCH_HEAD .git/MERGE_HEAD git commit 

这些命令看起来相当神秘。 在Mercurial我们做:

 hg pull --force <project-to-union-merge> hg merge hg commit 

注意Mercurial命令是简单而不是特殊的 – 唯一不寻常的是 – hg pull--force标志,这是需要的,因为当你从一个不相关的仓库中取出的时候Mercurial会中止。 正是这种差异使得Mercurial看起来更加优雅。

Git是一个平台,Mercurial是“只是”一个应用程序。 Git是一个版本化的文件系统平台,恰巧在箱子里装有一个DVCS应用程序,但是平常的平台应用程序比平台应用程序更复杂,边缘更粗糙。 但是这也意味着git的VCS是非常灵活的,并且你可以用git做非源代码控制的事情。

这是差异的本质。

Git最好从头开始理解 – 从存储库格式开始。 Scott Chacon的Git Talk是一个很好的入门书。 如果你试图在不知道引擎盖下发生了什么的情况下使用git,那么最终你会感到困惑(除非你只坚持非常基本的function)。 这听起来很愚蠢,只要你想要的是一个DVCS的日常编程例程,但git的天才是存储库格式其实很简单,你可以很容易地理解git的整个操作。

对于一些比较技术性的比较,我个人看到的最好的文章是Dustin Sallings':

  • Mercurial和Git的区别
  • Reddit线程,git经验丰富的Dustin回答了他自己的git新手问题

他实际上已经广泛地使用了两个DVCS,并且都很好地理解了它们,最终select了git。

最大的区别是在Windows上。 Mercurial是本地支持的,Git不是。 您可以使用bitbucket.org获得与github.com非常相似的托pipe(实际上,如果您获得免费的私有存储库,则会更好)。 我使用msysGit一段时间,但移动到Mercurial,并非常高兴。

如果您是Windows开发人员寻找基本断开版本控制,请使用Hg。 我发现Git是不可理解的,而Hg很简单,并与Windowsshell很好的集成。 我下载了Hg,并按照这个教程(hginit.com) – 十分钟后,我有一个本地回购,并回到我的项目上工作。

我认为关于“Mercurial vs. Git”的最好描述是:

“Git是Wesley Snipes,Mercurial是Denzel Washington”

他们几乎是相同的。 从我的angular度来看,最重要的不同点是(我的意思是让我select一个DVCS的原因)是两个项目如何pipe理分支机构。

要开始一个新的分支,使用Mercurial,你只需要将仓库克隆到另一个目录并开始开发。 然后,你拉和合并。 使用git,你必须明确给你要使用的新主题分支的名称,然后你开始使用相同的目录编码。

简而言之,Mercurial中的每个分支都需要自己的目录; 在git中,你通常在单个目录中工作。 在Mercurial中切换分支意味着更改目录; 在git中,这意味着要求git使用git checkout来更改目录的内容。

我很诚实:我不知道是否可以在Mercurial上做同样的事情,但是因为我通常在web项目上工作,总是使用与git相同的目录似乎对我很舒适,因为我不必重新configurationApache并重新启动它,我不会每次我分支时弄乱我的文件系统。

编辑:正如Deestan指出的,Hg已经命名了分支 ,它可以存储在一个存储库中,并允许开发人员在同一工作副本中切换分支。 git分支与Mercurial命名分支并不完全一样,无论如何:它们是永久性的,不会像git那样扔掉分支。 这意味着如果您使用命名的分支进行实验性任务,即使您决定永远不合并,它也会存储在存储库中。 这就是为什么Hg鼓励使用克隆进行实验性短时间运行的任务,并命名分支用于长期运行的任务,比如发布分支。

为什么很多Hg用户在命名分支上克隆的比社交或文化更多的是技术性的。 例如,在最后一个版本的Hg中,甚至可以closures一个已命名的分支,并从变更集中recursion地删除元数据。

另一方面,git邀请使用“命名分支”,这些分支不是永久的,并且不会作为元数据存储在每个变更集上。

那么,从我个人的angular度来看,git的模型与命名分支的概念有很深的联系,并且在一个分支和另一个分支之间切换同一个目录; hg可以对命名分支做同样的事情,但是它鼓励使用克隆,我个人不太喜欢。

gitmercurial之间有一个巨大的区别。 代表每个提交的方式。 git代表提交作为快照,而mercurial代表他们作为差异。

这在实践中意味着什么? 那么,git中的许多操作都比较快,例如切换到另一个提交,比较提交等。特别是如果这些提交很遥远。

AFAIK没有mercurial的方法的优势。

没有。 他们都这样做,都是平等的performance。 你应该select一个的唯一原因是如果你帮助一个已经使用一个项目..

select其中一个的另一个可能的原因是一个应用程序或服务只支持一个系统。例如,我非常喜欢github学习git。

还有谷歌的比较(虽然有点老,2008年完成)

http://code.google.com/p/support/wiki/DVCSAnalysis

如果我正确地理解了它们(而且我远离每个专家),它们在根本上都有不同的哲学。 我第一次使用了mercurial 9个月。 现在我已经使用Git 6。

hg是版本控制软件。 主要目标是跟踪一个软件的版本。

git是一个基于时间的文件系统。 目标是为文件系统添加另一个维度。 大部分都有文件和文件夹,git增加了时间。 它恰好作为一个VCS工作真棒是其devise的副产品。

在hg中,它总是试图维护整个项目的历史。 默认情况下,我相信hg在推拉时希望所有用户对所有对象所做的更改。

在git中,只有一组对象和这些跟踪文件(分支/头),这些文件确定哪些对象集表示特定状态下的文件树。 当推或拉git只发送你正在推或拉的特定分支所需的对象,这是所有对象的一个​​小子集。

就git而言,没有“1个项目”。 你可以有50个项目都在同一回购协议,git不会在意。 每个人都可以在相同的回购单独pipe理,生活正常。

Hg的分支概念是分支的主要项目或分支机构等。Git没有这样的概念。 git中的一个分支只是树的一个状态,一切都是git中的一个分支。 哪个分支是官方的,最新的或最新的在git中是没有意义的。

我不知道这是否有道理。 如果我可以画图片hg可能看起来像这样每个提交是一个o

  o---o---o / o---o---o---o---o---o---o---o \ / o---o---o 

一棵树和一根树枝从树枝上掉下来。 虽然git可以做到这一点,而且人们经常用这种方式来执行。 如果有这样的事情,一个混帐的图片可以很容易地看起来像这样

 o---o---o---o---o o---o---o---o \ o---o o---o---o---o 

事实上,在某些方面,在git中显示分支是没有意义的。

有一件事对于讨论来说很混乱,git和mercurial都有一个叫“分支”的东西,但是它们并不是一回事。 当不同的回购之间有冲突时,就会出现一个mercurial的分支。 git中的一个分支显然与hg中的一个克隆相似。 但是一个克隆,虽然它可能会给出类似的行为,但绝对不是一回事。 考虑我在git vs hg中使用铬回购,这是相当大的。

 $ time git checkout -b some-new-branch Switched to new branch 'some-new-branch' real 0m1.759s user 0m1.596s sys 0m0.144s 

现在在使用克隆的hg

 $ time hg clone project/ some-clone/ updating to branch default 29387 files updated, 0 files merged, 0 files removed, 0 files unresolved. real 0m58.196s user 0m19.901s sys 0m8.957 

这两个都是热门的。 也就是说,我跑了两次,这是第二次。 hg clone实际上和git-new-workdir是一样的。 这两个都创build了一个全新的工作目录,就好像你已经键入了cp -r project project-clone 。 这不同于在git中创build新分支。 这是更重的重量。 如果真的有相当于gg的分支,我不知道它是什么。

我知道在某种程度上,gg和git 也许可以做类似的事情。 如果是这样的话,他们引导您的工作stream程仍然存在巨大差异。 在git中,典型的工作stream程是为每个function创build一个分支。

 git checkout master git checkout -b add-2nd-joypad-support git checkout master git checkout -b fix-game-save-bug git checkout master git checkout -b add-a-star-support 

那只是创build了3个分支,每个分支都基于一个叫做master的分支。 (我敢肯定git中有一些方法可以让每行代替2行)

现在去做一件我刚刚做的事

 git checkout fix-game-save-bug 

并开始工作。 提交事物等。即使在一个像铬一样大的项目之间切换分支几乎是瞬间的。 我其实不知道该怎么做。 这不是我读过的任何教程的一部分。

另外一个很大的区别 Git的舞台

Git有这个阶段的想法。 你可以把它想象成一个隐藏的文件夹。 当你承诺你只承诺在舞台上,而不是你的工作树的变化。 这听起来很奇怪。 如果你想提交工作树中的所有更改,你可以做git commit -a ,它将所有的修改过的文件添加到舞台上,然后提交它们。

那么舞台的关键是什么? 你可以很容易地分离你的提交。 想象一下,你编辑joypad.cpp和gamesave.cpp,你想分开提交它们

 git add joypad.cpp // copies to stage git commit -m "added 2nd joypad support" git add gamesave.cpp // copies to stage git commit -m "fixed game save bug" 

Git甚至有命令来决定你想要复制到舞台的同一个文件中的哪些特定的行,所以你可以单独分割这些提交。 你为什么想这么做? 因为作为单独的提交,其他人可以只提取他们想要的提交,或者如果有问题,他们可以恢复提交问题。

在versioncontrolblog上有一个dynamic的比较图表,您可以比较几个不同的版本控制系统。

这是git,hg和bzr之间的比较表。

在与分支机构(特别是短期机构)合作方面存在相当大的差异。

这篇文章(BranchingExplained)解释了Mercurial与Git的比较。

您的项目中是否有基于Windows的协作者?

因为如果有的话,Git-for-Windows GUI看起来很尴尬,困难,不友善。

相比之下,Windows上的Mercurial则是一件不容易的事情。

有一点需要注意的是,bitbucket.org和github之间的mercurial是mercurial可以拥有任意数量的私有仓库,而github则需要升级到付费账户。 所以,这就是为什么我去使用mercurial的bitbucket。

去年某个时候,我对git和hg进行了评估,并决定使用hg。 我觉得它看起来像一个更清洁的解决scheme,并在当时更多的平台上更好地工作。 尽pipe如此,这大多是一种折腾。

最近,我开始使用git,因为git-svn和充当Subversion客户端的能力。 这赢了我,我现在已经完全切换到混帐。 我认为它的学习曲线稍微高一点(特别是如果你需要在内部捅一下),但这确实是一个很好的系统。 我要去读约翰现在发布的两篇比较文章。

我目前正在从SVN迁移到DVCS的过程中(同时写博客了解我的发现,我的第一个真正的博客工作…),我做了一些研究(谷歌search)。 据我所见,你可以用这两个软件包做大部分的事情。 看起来git有更多或更好的实现了高级function,我确实认为与Windows的集成比TortoiseHg更好一些。 我知道还有Git Cheetah(我也尝试过),但是mercurial解决scheme感觉更强大。

看到他们是如何开源的(对吧?)我不认为这两者都将缺乏重要的function。 如果有什么重要的东西,人们会问,人们会编码。

我认为对于常见的做法,Git和Mercurial绰绰有余。 他们都有使用它们的大项目(Git – > linux内核,Mercurial – > Mozilla基础项目,当然这两者当中),所以我不认为其中任何一个都是真的缺乏一些东西。

这就是说,我对其他人对此有兴趣,因为这将成为我的博客努力的重要来源;-)

在InfoQ的DVCS指南中 ,有一个关于git,Mercurial和Bazaar的详尽而详尽的比较表格和图表。

我意识到这不是答案的一部分,但是在这个说明中,我也认为像NetBeans和Eclipse这样的平台的稳定插件的可用性在哪个工具中更适合于该任务,或者更确切地说,哪个工具是“你”的最佳select。 也就是说,除非你真的想用CLI的方式来做。

Eclipse(以及基于它的所有东西)和NetBeans都有远程文件系统(如SSH)和文件外部更新的问题; 这也是你为什么要“无缝”工作的另一个原因。

我现在也试图为自己回答这个问题..我已经把候选人归结为Git或Mercurial ..谢谢大家提供有用的投入在这个话题上,没有去宗教信仰。

还有一个有趣的比较mercurial和git: Mercurial vs Git 。 主要关注内部及其对分支过程的影响。

如果你对Mercurial和Git的性能比较感兴趣,请看这篇文章 。 结论是:

Git和Mercurial都有很好的数据,但是在速度和版本库大小之间做了一个有趣的折衷。 Mercurial的增加和修改速度都很快,同时还能保持存储库的增长。 Git速度也很快,但是它的存储库会随着修改后的文件快速增长,直到重新打包为止 – 而且这些重新打包的速度可能会非常慢。 但是打包的仓库比Mercurial小得多。

mercurial网站对这两个系统的异同进行了很好的描述 ,解释了词汇和底层概念的差异。 作为一个很长时间的git用户,它确实帮助我理解了Mercurial的思维模式。

如果你正在从SVN迁移,使用Mercurial作为它的语法是SVN用户更容易理解。 除此之外,你也不能出错。 但在select其中之一之前,请检查GIT教程和HGinit 。

有人认为VCS系统必须复杂。 他们鼓励在这个领域发明术语和概念。 他们可能会认为关于这个问题的许多博士学位将是有趣的。 其中可能是那些deviseGit。

Mercurial的devise思路是不同的。 开发人员不应该太在意VCS,而应该把时间花在他们的主要function上:软件工程。 Mercurial允许用户使用并愉快地滥用系统而不让他们犯任何不可恢复的错误。

任何专业工具都必须带有清晰的devise和直观的CLI。 Mercurial用户可以通过发出简单的命令而不需要任何奇怪的选项来完成大部分的工作。 在Git双重短跑,疯狂的选项是常态。 如果你是一个CLI人员(说实话,任何一个自称是软件工程师的人),Mercurial都有很大的优势。

举个例子,假设你犯了一个错误提交。 你忘了编辑一些文件。 要在Mercurial中撤销您的操作,只需键入:

$ hg rollback

然后,您会收到一条消息,表示系统将撤消您的上次交易。

在Git中你必须input:

$ git reset --soft HEAD^

所以好吧,假设你有一个想法是什么重置是关于。 但是除此之外,你必须知道“软”和“硬”重置是什么(任何直觉的猜测?)。 哦,当然,不要忘记最后的'^'字符! (现在里奇的名字是…)

Mercurial与第三方工具如kdiff3和meld的整合也好多了。 生成你的补丁合并你的分支没有太多的大惊小怪。 Mercurial还包括一个简单的http服务器,您可以通过键入来激活

hg serve

让其他人浏览你的资源库。

底线是,Git做了Mercurial所做的事情,以一种更为复杂的方式,并且使用了更为低劣的CLI。 如果你想把你的项目的VCS变成一个科学研究领域,就使用Git。 如果您想要完成VCS工作而不关心它,请使用Mercurial,并专注于您的实际任务。