我已经在Windows上使用git(使用msysGit)一段时间了,我喜欢分布式源代码管理的想法。就在最近,我一直在研究Mercurial(hg),它看起来很有趣。然而,我无法理解hg和git之间的区别。
有人对git和hg进行过并排比较吗?我很想知道hg和git有什么不同,而不必参与粉丝讨论。
我已经在Windows上使用git(使用msysGit)一段时间了,我喜欢分布式源代码管理的想法。就在最近,我一直在研究Mercurial(hg),它看起来很有趣。然而,我无法理解hg和git之间的区别。
有人对git和hg进行过并排比较吗?我很想知道hg和git有什么不同,而不必参与粉丝讨论。
这些文章可能有助于:
编辑:将Git和Mercurial与名人进行比较似乎是一种趋势。这里还有一个:
我在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提供在线托管,Bitbucket的服务很棒,响应迅速(我还没有尝试过github)。
我选择Mercurial是因为它感觉干净优雅——我被Git的shell/Perl/Ruby脚本所困扰。试试看git instaweb.sh
文件如果你想知道我的意思:这是一个shell脚本,它生成一个Ruby剧本,我认为它运行一个网络服务器。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命令是多么简单,一点也不特殊——唯一不寻常的是--force
标志到hgpull
,这是必需的,因为当您从不相关的存储库中提取时,Mercurial会中止。正是这样的差异让Mercurial在我看来更优雅。
Git是一个平台,Mercurial“只是”一个应用程序。Git是一个版本化的文件系统平台,它碰巧附带了一个DVCS应用程序,但对于平台应用程序来说,它比专注的应用程序更复杂,边缘也更粗糙。但这也意味着Git的VCS非常灵活,你可以用Git做大量非源代码控制的事情。
这就是区别的本质。
Git最好从底层开始理解——从存储库格式开始理解Scott Chacon的Git Talk是一本很好的入门读物。如果你试图在不知道引擎盖下发生了什么的情况下使用Git,你会在某个时候感到困惑(除非你只坚持非常基本的功能)。当你只需要一个用于日常编程的DVCS时,这听起来可能很愚蠢,但git的天才之处在于存储库格式实际上非常简单,而且你可以很容易地理解git的整个操作。
对于一些更技术性的比较,我个人看过的最好的文章是Dustin Sallings的:
事实上,他已经广泛使用了这两种DVCS,并且对它们都很了解——最终他更喜欢git。
最大的区别在于Windows。Mercurial本机支持,Git不支持。您可以获得与github.com与bitbucket.org(实际上,如果你有一个免费的私人存储库,情况会更好)。我使用msysGit有一段时间了,但后来转到了Mercurial,对此我很满意。
如果您是一名Windows开发人员,正在寻找基本的断开连接的修订控制,请使用Hg。我发现Git很难理解,而Hg很简单,并且与Windows外壳集成得很好。我下载了Hg并关注了本教程(hginit.com)-十分钟后,我有了一个本地回购,然后又开始了我的项目。
我认为关于“Mercurial vs.Git”的最佳描述是:
They are almost identical. The most important difference, from my point of view (I mean, the reason that got me to choose one DVCS over the other) is how the two programs manage branches.
To start a new branch, with Mercurial, you simply clone the repository to another directory and start developing. Then, you pull and merge. With git, you have to explicitly give a name to the new topic branch you want to use, then you start coding using the same directory.
In short, each branch in Mercurial needs its own directory; in git you usually work in on single directory. Switching branches in Mercurial means changing directories; in git, it means asking git to change the directory s content with git checkout.
老实说:我不知道Mercurial是否也可以这样做,但由于我通常在web项目上工作,所以使用git始终使用同一目录对我来说似乎很舒服,因为我不必重新配置Apache并重新启动它,而且每次分支时也不会弄乱我的文件系统。
编辑:正如Deestan所指出的,Hg有命名分支,这些分支可以存储在单个存储库中,并允许开发人员在同一工作副本中切换分支。无论如何,git分支与Mercurial命名的分支并不完全相同:它们是永久的,不会像git中那样丢弃分支。这意味着,如果您将命名分支用于实验任务,即使您决定从不合并它,它也将存储在存储库中。这就是为什么Hg鼓励将克隆用于实验性的、短期运行的任务,并将命名分支用于长期运行的任务(如发布分支)的原因。
许多汞用户更喜欢克隆而不是命名分支的原因更多是社会或文化因素,而不是技术因素。例如,对于Hg的最新版本,甚至可以关闭一个命名分支并递归地从变更集中删除元数据。
另一方面,git邀请使用“命名分支”,这些分支不是永久的,也不会作为元数据存储在每个变更集中。
从我个人的角度来看,gits模型与命名分支的概念有着深刻的联系,并在同一目录中的一个分支和另一个分支之间切换;hg可以对命名分支做同样的事情,但它鼓励使用克隆,我个人不太喜欢克隆。
git和mercurial之间存在一个巨大的差异;表示每次提交的方式git将提交表示为快照,而mercurial则将它们表示为diff。
这在实践中意味着什么?好吧,很多操作在git中都更快,比如切换到另一个提交,比较提交等等。特别是如果这些提交距离很远的话。
AFAIK认为mercurial的方法没有任何优势。
没有什么他们做的都一样,表现也差不多。你应该选择一个而不是另一个的唯一原因是,如果你帮助一个已经使用了一个的项目。。
选择其中一个的另一个可能原因是只支持其中一个系统的应用程序或服务。。例如,我之所以选择学习git,很大程度上是因为github。。
还有谷歌的比较(尽管它有点旧,是在2008年做的)
如果我正确理解它们(而且我还不是每一个方面的专家),它们基本上都有不同的哲学。我第一次使用汞有9个月了。现在我已经用git 6了。
hg是版本控制软件。它的主要目标是跟踪一个软件的版本。
git是一个基于时间的文件系统。它的目标是为文件系统添加另一个维度。大多数都有文件和文件夹,git增加了时间。它恰好作为VCS工作得很好,这是它设计的副产品。
在hg中,它总是试图维护整个项目的历史。默认情况下,我认为hg希望所有用户在推拉时对所有对象进行所有更改。
在git中,只有一个对象池和这些跟踪文件(分支/头),它们决定了哪一组对象代表特定状态下的文件树。当推动或拉动git时,它只发送您正在推动或拉动的特定分支所需的对象,这是所有对象的一个子集。
就git而言,没有“1项目”。你可以在同一个回购中有50个项目,git不会在意。每一个都可以在同一个回购中单独管理,并且过得很好。
Hg的分支概念是主项目的分支或分支等。Git没有这样的概念。git中的一个分支只是树的一种状态,所有的东西都是git中一个分支。哪一个分支是官方的、当前的还是最新的,在git中没有意义。
我不知道这是否有意义。如果我能画出图片,hg可能看起来像这样,其中每个提交都是一个<code>o</code>
o---o---o
/
o---o---o---o---o---o---o---o
/
o---o---o
一棵只有一个树根和树枝的树。虽然git可以做到这一点,而且人们经常以这种方式使用它,但这并不是强制性的。一张git图片,如果有这样的东西的话,很容易看起来像这样
o---o---o---o---o
o---o---o---o
o---o
o---o---o---o
事实上,在某些方面,用git显示分支甚至没有意义。
有一件事让讨论非常困惑,git和mercurial都有一个被称为“分支”的东西,但它们完全不同。当不同的回购协议之间发生冲突时,mercurial就会出现分支。git中的一个分支显然类似于hg中的克隆。但是,克隆人虽然可能会有类似的行为,但肯定是不一样的。考虑一下我使用相当大的铬回购在git和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相同。这两种方法都创建了一个全新的工作目录,几乎就像您键入了cp-r项目克隆
一样。这与在git中创建一个新分支不同。它的重量要重得多。如果hg中存在gits分支的真正等价物,我不知道它是什么。
我知道在某种程度上hg和git可能能够做类似的事情。如果是这样的话,那么他们引导你的工作流程仍然有很大的不同。在git中,典型的工作流程是为每个功能创建一个分支。
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
That just created 3 branches, each based off a branch called master. (I m sure there s some way in git to make those 1 line each instead of 2)
现在我要做一个
git checkout fix-game-save-bug
并开始工作。提交事务等。即使在chrome这样大的项目中,在分支之间切换也几乎是瞬间的。事实上,我不知道如何在hg中做到这一点。这不是我读过的任何教程的一部分。
另一个很大的区别。Git的阶段。
Git对舞台有这样的想法。你可以把它看作一个隐藏的文件夹。当你提交时,你只提交舞台上的内容,而不是工作树中的更改。这听起来可能很奇怪。如果你想提交工作树中的所有更改,你可以执行<code>git commit-一个</code>,它将所有修改过的文件添加到stage中,然后提交它们。
那么这个舞台有什么意义呢?您可以很容易地分离提交。想象一下,您编辑了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甚至有命令来决定要将同一文件中的哪些特定行复制到stage,这样您也可以单独拆分这些提交。你为什么要这么做?因为作为单独的提交,其他人只能提取他们想要的提交,或者如果出现问题,他们可以只恢复有问题的提交。
在版本控制博客上有一个动态比较图,您可以在这里比较几种不同的版本控制系统。
在与分支机构(尤其是短期分支机构)合作时,存在着相当显著的差异。
在这篇文章(BranchingExplained)将Mercurial与Git进行了比较。
你的项目中有基于Windows的合作者吗?
因为如果有的话,Git for Windows GUI看起来很尴尬、困难、不友好。
相比之下,Windows上的Mercurial是一个无需思考的问题。
bitbucket.org的mercurial和github的git之间需要注意的一点是,mercurial可以拥有你想要的任意多的私人存储库,但github必须升级到付费帐户。所以,这就是为什么我选择使用汞的比特桶。
去年的某个时候,我评估了git和hg以供自己使用,并决定使用hg。我觉得这看起来是一个更清洁的解决方案,而且当时在更多的平台上效果更好。不过,这主要是一场掷硬币游戏。
最近,我开始使用git,因为git svn和作为Subversion客户端的能力。这赢得了我的支持,现在我已经完全转向了git。我认为它有一个略高的学习曲线(尤其是如果你需要深入了解内部),但它确实是一个很棒的系统。我要去看约翰现在发表的那两篇比较文章。
I m currently in the process of migrating from SVN to a DVCS (while blogging about my findings, my first real blogging effort...), and I ve done a bit of research (=googling). As far as I can see you can do most of the things with both packages. It seems like git has a few more or better implemented advanced features, I do feel that the integration with windows is a bit better for mercurial, with TortoiseHg. I know there s Git Cheetah as well (I tried both), but the mercurial solution just feels more robust.
看到它们都是开源的(对吧?),我认为它们都不会缺少重要的功能。如果某件事很重要,人们会要求它,人们会编码它。
我认为对于常见的实践来说,Git和Mercurial已经足够了。他们都有使用它们的大型项目(当然,Git->;linux内核、Mercurial->;Mozilla基础项目等),所以我不认为他们真的缺少什么。
话虽如此,我对其他人对此的看法很感兴趣,因为这将是我写博客的一个很好的来源;-)
我意识到这不是答案的一部分,但在这一点上,我也认为NetBeans和Eclipse等平台的稳定插件的可用性在哪个工具更适合任务中发挥了作用,或者更确切地说,哪个工具最适合“你”。也就是说,除非您真的想要以CLI的方式执行此操作。
Eclipse(以及基于它的一切)和NetBeans有时都会遇到远程文件系统(如SSH)和文件的外部更新问题;这也是为什么你希望你选择的任何东西都能“无缝”工作的另一个原因。
我现在也在试着自己回答这个问题。。我已经把候选人归结为Git或Mercurial。。感谢大家在不信教的情况下就这个话题提供了有用的意见。
Yet another interesting comparison of mercurial and git: Mercurial vs Git. Main focus is on internals and their influence on branching process.
如果您对Mercurial和Git的性能比较感兴趣,请查看本文。结论是:
Git和Mercurial都取得了不错的成绩,但在速度和存储库大小之间进行了有趣的权衡。Mercurial在添加和修改方面都很快,同时可以控制存储库的增长。Git也很快,但在重新打包之前,它的存储库会随着修改后的文件而快速增长,而这些重新打包可能会很慢。但打包的存储库比Mercurial的要小得多。
mercurial网站有一个很好地描述了两个系统之间的异同,解释了词汇和基本概念的差异。作为一个长期的git用户,这确实帮助我理解了Mercurial的心态。
This link may help you to understand the difference http://www.techtatva.com/2010/09/git-mercurial-and-bazaar-a-comparison/
有些人认为VCS系统必须是复杂的。他们鼓励在现场发明术语和概念。他们可能会认为许多关于这个主题的博士学位会很有趣。其中可能包括设计Git的人。
Mercurial的设计理念不同。开发人员不应该太关心VCS,而是应该把时间花在他们的主要功能上:软件工程。Mercurial允许用户使用并愉快地滥用系统,而不会让他们犯任何不可恢复的错误。
任何专业工具都必须配备设计清晰、直观的CLI。Mercurial用户可以通过发出简单的命令来完成大部分工作,而不需要任何奇怪的选项。在Git双破折号中,疯狂的选项是常态。如果你是一名CLI人员,Mercurial就有很大的优势(老实说,任何自尊的软件工程师都应该是)。
举个例子,假设你犯了一个错误。你忘了编辑一些文件。要撤消Mercurial中的操作,只需键入:
$hg回滚
然后,您会得到一条消息,系统将撤消您的最后一笔交易。
在Git中,您必须键入:
$git重置--软头^
所以,好吧,假设你知道重置是关于什么的。但除此之外,您还必须知道“--soft”和“--hard”重置是什么(有直观的猜测吗?)。哦,当然,最后不要忘记^这个字符!(现在里奇的名字是什么…)
Mercurial与kdiff3和meld等第三方工具的集成也要好得多。生成你的补丁,合并你的分支,而不需要太多麻烦。Mercurial还包括一个简单的http服务器,您可以通过键入
hg服务
让其他人浏览您的存储库。
最重要的是,Git做了Mercurial所做的事情,其方式要复杂得多,CLI也要差得多。如果你想把项目的VCS变成一个科学研究领域,请使用Git。如果你想在不太关心VCS的情况下完成它,并专注于你的实际任务,那么就使用Mercurial。