git - 作为一个有经验的 git 用户,我怎样才能学会理解 Mercurial 的工作原理?

标签 git version-control mercurial dvcs

我已经使用 git 一段时间了,因为它是我唯一使用过的 DVCS,所以我学会了非常依赖它在我的工作流程中的工作方式。

我现在在一家新公司工作,他们使用 Mercurial,所以我需要了解 Mercurial 的模型以及它与 git 的不同之处,以适应我的工作流程并避免犯下代价高昂的错误。

那么我可以使用哪些资源呢?

最佳答案

相当延伸 concept differences from Mercurial's official wiki .

来自 stackoverflow 的另一个问题:Git equivalents of most common Mercurial commands?

评论跟进:

如果我继续:“模型”、“差异”、“差异背后的哲学”以及对“工作流程”的影响。在我能想到的差异中,有:

  • 对于工作流,除了缺少暂存区之外,您应该能够坚持您的旧做法(何时提交,何时分支,何时 merge ,...)。
  • 分支哲学的主要区别在于,Mercurial 克隆所有分支时,Git 只克隆指定的分支(如果只想要一个分支,可以,但需要配置)。
  • merge 哲学并没有真正不同。 Git 可以 merge 两个或多个头,但 Mercurial 只能 merge 两个头(你 merge 过更多吗?)。
  • 关于重命名的理念大不相同,每个设计师都为自己的观点辩护。随着 Mercurial 轨道的重命名, merge 变得更加容易。如果您使用“递归”策略,Git 会尝试在 merge 时猜测重命名。
  • 存储在实现上有很大不同,但在概念上没有区别(正如您要求的“模型”,我将提供更多详细信息):
  • Git 将数据存储为 "objects" (“提交对象”、“树对象”、“blob 对象”或“标记对象”,存储为由名称唯一标识的文件,该名称是 SHA1 哈希)。这是某种“文件系统哈希表”。使用最新版本,可以将这些对象打包以减少 .git/objects 下的小文件。目录。我不会走得更远,我的理解到此为止,因为我从来没有发现知道比特是如何铺设的。您可以在对象的内容中进行 pretty-print :
    git show -s --format=raw <commitid> # changeset content
    git ls-tree <treeid> # list tree content
    git show <fileid> # blob content
    
  • Mercurial stores每个文件的历史记录单独作为 "revlog(NG)" format 中的“文件日志” .您可以手动检查 .hg/store/data 下的文件名(revlogNG)。请注意,特殊字符和大写字符是“tilda-underscore 编码”。

    您可以列出文件的修订版本:
    hg debugindex .hg/store/data/<file>.i # hg debugindex <file> also works but you see less of internals
    

    您已经注意到 nodeid s 不是 hg log 中的那个.

    现在,检查内容:
    hg debugdata .hg/store/data/<file>.i <nodeid>
    

    修订历史(或多或少你看到的 hg log )存储在 .hg/store/00changelog.i 中。 (使用 hg debugindex .hg/store/00changelog.i 检查它,您将在 hg log 列中看到与 nodeid 中的 ID 相同的 ID)。显示一个 ID 为 XXXX 的原始历史条目, 类型 hg debugdata .hg/store/00changelog.i XXXX在一个终端。 (看第一行,后面会用到 YYYY )

    树的状态存储在 .hg/store/00manifest.i .对应的nodeid list 中是 YYYY .
    hg debugdata .hg/store/00manifest.i YYYY
    

    这将显示附加的“文件名+节点ID”列表。让我们选择文件 foo/bar并注意 nodeid附加到它并认为它是 ZZZZ (行 foo/barZZZZ)。

    最后一步,访问foo/bar的内容文件:
    hg debugdata .hg/store/data/foo/bar.i ZZZZ
    
  • 从这个基本的数据存储分析中可以清楚地看出哲学上的差异:
  • 当 Git 提交时,它会生成(可能很多)新文件(可以稍后打包)。当 Mercurial 提交时,它会附加到现有文件中。
  • 在 Git 中 blobid可以与 treeid 碰撞(或 commitidtagid )但这是极不可能的。在 Mercurial 中,一个 changesetid只能与另一个碰撞 changesetid ( list (树)和文件(blob)也是如此),这更不可能。
  • 在 Git 中,标签是特殊的对象,在 Mercurial 中,它只是存储库中文件中的列表(通过一些 rules 可以知道哪个修改后的相同标签的副本获胜)。
  • 在 Mercurial 中,默认情况下没有“修改”或“rebase”,它是一种设计选择(哲学?),始终附加,从不删除内容,因为它会导致并发问题。但是可以通过扩展来实现。
  • 关于git - 作为一个有经验的 git 用户,我怎样才能学会理解 Mercurial 的工作原理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7331849/

    相关文章:

    git - 检查提交是否 merge 到另一个分支,如果是, merge 提交是什么?

    version-control - 哪些源代码控制系统具有文件级权限?

    version-control - 团队基础服务器 : does TFS do the auto merge or the local merge tool?

    mercurial - 检查当前目录是否在 Mercurial 下的最快方法?

    version-control - "push creates new remote head"问题

    java - 如何将 gradle 多项目存储库作为 git 子模块包含在另一个 gradle 项目中

    git - 模拟预提交钩子(Hook) Bitbucket Cloud

    java - Eclipse 项目到 mercurial

    git - 致命 : Could not read from remote repository. Github 错误:无法将某些引用推送到

    windows - Git:在 Windows 中协调两个具有重复名称(大小写不同)的文件夹,同时保留历史记录