我已经在 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.comhttp://bitbucket.org 提供在线托管,Bitbucket 的服务很棒且响应迅速(我还没有尝试过 github)。

我选择了 Mercurial,因为它给人干净、优雅的感觉——我对使用 Git 获得的 shell/Perl/Ruby 脚本感到厌烦。尝试看一下 git-instaweb.sh 文件 如果你想知道我的意思:它是一个 生成一个脚本 红宝石 脚本,我认为它运行一个网络服务器。shell 脚本生成另一个 shell 脚本来启动第一个 Ruby 脚本。还有一点 珀尔, ,为了更好的衡量。

我喜欢 博客文章 将 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 标记为 hg pull, ,这是必需的,因为当您从不相关的存储库中提取数据时,Mercurial 将中止。正是这样的差异让 Mercurial 对我来说显得更加优雅。

Git 是一个平台,Mercurial “只是”一个应用程序。Git 是一个版本控制的文件系统平台,恰好附带了 DVCS 应用程序,但与平台应用程序一样,它比专注的应用程序更复杂且边缘更粗糙。但这也意味着 git 的 VCS 非常灵活,并且您可以使用 git 做大量非源代码控制的事情。

这就是差异的本质。

最好从头开始理解 Git——从存储库格式开始。 Scott Chacon 的 Git 演讲 是一个很好的入门读物。如果您在不知道幕后发生了什么的情况下尝试使用 git,那么您最终会在某些时候感到困惑(除非您只坚持非常基本的功能)。当您想要的只是日常编程例程的 DVCS 时,这可能听起来很愚蠢,但 git 的天才之处在于存储库格式实际上非常简单,并且您可以 很容易理解git的整个操作。

对于一些更注重技术性的比较,我个人见过的最好的文章是达斯汀·塞林斯(Dustin Sallings)的:

实际上,他广泛使用了这两种 DVCS,并且对它们都有很好的理解——最终更喜欢 git。

最大的区别是在 Windows 上。Mercurial 本身受支持,而 Git 则不受支持。您可以获得非常相似的托管 github.combitbucket.org (实际上,当您获得免费的私人存储库时,效果会更好)。我使用 msysGit 一段时间,但后来转向 Mercurial,并且对它非常满意。

如果您是一名 Windows 开发人员,正在寻找基本的断开版本控制,请选择 Hg。我发现 Git 难以理解,而 Hg 很简单并且与 Windows shell 集成得很好。我下载了 Hg 并关注 本教程(hginit.com) - 十分钟后,我有了一个本地存储库,并重新开始我的项目。

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

“吉特是韦斯利·斯奈普斯。Mercurial 就是丹泽尔·华盛顿”

它们几乎完全相同。从我的角度来看,最重要的区别(我的意思是,让我选择一种 DVCS 而不是另一种的原因)是这两个程序管理分支的方式。

要使用 Mercurial 启动新分支,您只需克隆存储库 到另一个目录 并开始开发。然后,您拉动并合并。使用 git,您必须明确为要使用的新主题分支命名,然后开始编码 使用相同的目录.

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

我是诚实的:我不知道是否可以对 Mercurial 执行相同的操作,但由于我通常处理 Web 项目,因此使用 git 始终使用相同的目录对我来说似乎很舒服,因为我不必重新配置 Apache 并重新启动它而且我每次分支时都不会弄乱我的文件系统。

编辑:正如迪斯坦指出的那样,汞 命名分支, ,它可以存储在单个存储库中,并允许开发人员在同一工作副本内切换分支。无论如何,git 分支与 Mercurial 命名分支并不完全相同:它们是永久性的,不会像 git 那样丢弃分支。这意味着,如果您使用命名分支进行实验任务,即使您决定永远不合并它,它也会存储在存储库中。这就是为什么 Hg 鼓励使用克隆来执行实验性的、短期运行的任务,并使用命名分支来执行长期运行的任务,例如发布分支。

许多 Hg 用户更喜欢克隆而不是命名分支的原因更多是社会或文化而不是技术。例如,在 Hg 的最新版本中,甚至可以关闭命名分支并递归地从变更集中删除元数据。

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

从我个人的角度来看,git 的模型与命名分支和同一目录下的分支和另一个分支之间的切换的概念有着深刻的联系;hg 可以对命名分支执行相同的操作,但它鼓励使用克隆,我个人不太喜欢克隆。

有一个 巨大的 之间的区别 git水银;代表每次提交的方式。 git 将提交表示为快照,而 水银 将它们表示为差异。

这在实践中意味着什么?嗯,很多操作在 git 中都更快,比如切换到另一个提交、比较提交等。特别是如果这些提交距离很远。

AFAIK Mercurial 的方法没有任何优势。

没有什么。他们都做同样的事情,表现也差不多。您应该选择其中一种而不是另一种的唯一原因是,如果您帮助一个已经使用其中一种的项目。

选择一个的另一个可能原因是应用程序或服务仅支持其中一个系统。例如,我几乎选择学习 git 因为 github..

还有google的比较(虽然有点旧,2008年做的)

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

如果我对它们的理解正确的话(而且我远非每个领域的专家),那么它们从根本上来说都有不同的哲学。我第一次使用 Mercurial 已有 9 个月了。现在我已经使用 git 6 了。

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

git 是一个基于时间的文件系统。它的目标是为文件系统添加另一个维度。大多数都有文件和文件夹,git 增加了时间。作为 VCS,它的出色表现是其设计的副产品。

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

在 git 中,只有一个对象池和这些跟踪文件(分支/头),它们确定哪些对象集代表特定状态下的文件树。当推送或拉动时,git 仅发送您正在推送或拉动的特定分支所需的对象,这是所有对象的一小部分。

就 git 而言,不存在“1 项目”。您可以在同一个存储库中拥有 50 个项目,而 git 不会在意。每一个都可以在同一个存储库中单独管理,并且生活得很好。

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

我不知道这是否有意义。如果我可以画图 hg 可能看起来像这样,其中每个提交都是一个 o

             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 中的克隆。但是克隆虽然可能会给出类似的行为,但它绝对不一样。考虑一下我使用相当大的 chromium 存储库在 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 project project-clone. 。这与在 git 中创建新分支不同。它的重量要重得多。如果 hg 中存在真正相当于 git 分支的东西,我不知道它是什么。

我在某种程度上理解 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

这刚刚创建了 3 个分支,每个分支都基于一个名为 master 的分支。(我确信 git 中有某种方法可以使每行 1 行而不是 2 行)

现在开始做我刚刚做的一个

git checkout fix-game-save-bug

并开始工作。承诺事情等等。即使在像 chrome 这样大的项目中,分支之间的切换也几乎是瞬时的。我实际上不知道如何在 hg 中做到这一点。它不是我读过的任何教程的一部分。

另一个很大的区别。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 甚至有命令来决定要将同一文件中的哪些特定行复制到阶段,以便您也可以单独拆分这些提交。你为什么想这么做?因为作为单独的提交,其他人只能提取他们想要的提交,或者如果出现问题,他们可以只恢复有问题的提交。

版本控制博客上有一个动态比较图表,您可以在其中比较几种不同的版本控制系统。

这是 git、hg 和 bzr 之间的对照表。

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

它的解释是 这篇文章(分支解释) 其中比较了 Mercurial 和 Git。

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

因为即使有,Git-for-Windows GUI 也会显得笨拙、困难、不友好。

相比之下,Mercurial-on-Windows 是一个显而易见的选择。

在 bitbucket.org 的 Mercurial 和 github 的 git 之间需要注意的一点是,mercurial 可以拥有任意数量的私有存储库,但是 github 必须升级到付费帐户。所以,这就是为什么我选择使用 Mercurial 的 bitbucket。

去年的某个时候,我评估了 git 和 hg 供我自己使用,并决定使用 hg。我觉得它看起来是一个更干净的解决方案,并且当时在更多平台上运行得更好。不过,这主要是一个折腾。

最近,我开始使用 git,因为 git-svn 以及充当 Subversion 客户端的能力。这赢得了我的支持,我现在已经完全转向 git。我认为它的学习曲线稍高(特别是如果您需要深入研究内部),但它确实是一个很棒的系统。我要去阅读约翰现在发布的两篇比较文章。

我目前正在从 SVN 迁移到 DVCS(同时在博客中讲述我的发现,我的第一个真正的博客工作......),并且我已经做了一些研究(=谷歌搜索)。据我所知,您可以使用这两个软件包完成大部分操作。Git似乎具有更多或更好的实现高级功能,我确实觉得与Windows的集成对Mercurial和Tortoisehg有点更好。我知道还有 Git Cheetah(我都尝试过),但善变的解决方案感觉更强大。

看看它们都是开源的(对吧?),我认为它们都不会缺乏重要的功能。如果某件事很重要,人们就会要求它,人们就会对其进行编码。

我认为对于常见的实践来说,Git 和 Mercurial 就足够了。他们都有使用它们的大型项目(Git -> linux 内核,Mercurial -> Mozilla 基础项目,当然还有其他项目),所以我不认为他们真的缺少什么。

话虽这么说,我对其他人对此的看法很感兴趣,因为这将为我的博客工作提供一个很好的来源;-)

在 git、Mercurial 和 Bazaar 上有一个很棒且详尽的比较表和图表 InfoQ 关于 DVCS 的指南.

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

Eclipse(以及基于它的所有内容)和 NetBeans 有时都会出现远程文件系统(例如 SSH)和文件外部更新的问题;这也是您希望您选择的任何内容都能“无缝”工作的另一个原因。

我现在也在尝试为自己回答这个问题..我将候选者归结为 Git 或 Mercurial ..感谢大家在不信教的情况下就这个话题提供了有用的意见。

Mercurial 和 git 的另一个有趣的比较: Mercurial 与 Git。主要关注的是内部结构及其对分支过程的影响。

如果您对 Mercurial 和 Git 的性能比较感兴趣,请查看 本文. 。结论是:

Git 和 Mercurial 都取得了不错的成绩,但在速度和存储库大小之间做出了有趣的权衡。Mercurial 的添加和修改速度都很快,同时可以控制存储库的增长。Git 也很快,但它的存储库随着修改的文件而增长得非常快,直到您重新打包 - 而这些重新打包可能会非常慢。但打包后的存储库比 Mercurial 的小得多。

Mercurial 网站有一个 对相似点和不同点的精彩描述 两个系统之间的差异,解释词汇和基本概念的差异。作为一个长期的 git 用户,它确实帮助我理解了 Mercurial 的心态。

如果您要从 SVN 迁移,请使用 Mercurial,因为它的语法对于 SVN 用户来说更容易理解。除此之外,你都不会出错。但一定要检查一下 git教程HG初始化 在选择其中之一之前。

有些人认为 VCS 系统一定很复杂。他们鼓励在该领域发明术语和概念。他们可能会认为许多关于该主题的博士学位会很有趣。其中可能包括设计 Git 的人。

Mercurial 的设计理念不同。开发者不应该太关心VCS,而应该把时间花在他们的主要功能上:软件工程。Mercurial 允许用户愉快地使用和滥用该系统,而不会让他们犯任何不可恢复的错误。

任何专业工具都必须配备设计清晰且直观的 C​​LI。Mercurial 用户可以通过发出简单的命令来完成大部分工作,而无需任何奇怪的选项。在 Git 双划线中,疯狂的选项是常态。如果您是 CLI 人员(老实说,任何有自尊心的软件工程师都应该如此),Mercurial 具有很大的优势。

举个例子,假设你错误地进行了一次提交。您忘记编辑一些文件。要撤消 Mercurial 中的操作,您只需键入:

$ hg rollback

然后您会收到一条消息,表明系统撤消了您的上一笔交易。

在 Git 中你必须输入:

$ git reset --soft HEAD^

好吧,假设您知道重置是什么意思。但除此之外,您还必须知道什么是“--soft”和“--hard”重置(有任何直观的猜测吗?)。哦,当然不要忘记最后的“^”字符!(现在里奇的名字是什么......)

Mercurial 与 kdiff3 和 meld 等第三方工具的集成也更好。生成补丁并合并您的分支,无需大惊小怪。Mercurial 还包括一个简单的 http 服务器,您可以通过键入来激活它

hg serve

并让其他人浏览您的存储库。

底线是,Git 做 Mercurial 所做的事情,但方式要复杂得多,而且 CLI 也差得多。如果您想将项目的 VCS 转变为科学研究领域,请使用 Git。如果您想完成 VCS 工作而不用太关心它,并专注于您的实际任务,请使用 Mercurial。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top