作为一名经验丰富的 git 用户,我如何学习了解 Mercurial 的工作原理?

发布于 2024-12-03 05:44:40 字数 183 浏览 0 评论 0原文

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

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

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

I've been using git for a while now, and since it is the only DVCS I have ever used, I've learned to rely a lot on the way it works for my workflow.

I'm in a new company now, and they use Mercurial, so I need to understand Mercurial's model and how it differs from git, to adapt my workflow and avoid making costly mistakes.

So what resources can I use for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜中书 2024-12-10 05:44:40

相当广泛的与 Mercurial 官方 wiki 的概念差异

stackoverflow 的另一个问题:最常见 Mercurial 的 Git 等效项命令?

评论跟进:

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

  • 对于工作流程,除了缺乏暂存区域之外,您应该能够坚持您的旧做法(何时提交,何时分支,何时合并,...)。
  • 关于分支的理念的主要区别在于,当 Mercurial 克隆所有分支时,Git 只克隆指定的分支(如果你只想要一个分支,这是可以的,但需要配置)。
  • 合并理念并没有真正不同。 Git 可以合并两个或多个头,但 Mercurial 只能合并两个头(你合并过更多头吗?)。
  • 关于重命名的理念差异很大,每个设计师都捍卫了自己的观点。随着 Mercurial 跟踪重命名,合并会变得更加容易。如果您使用“递归”策略,Git 会尝试在合并时猜测重命名。
  • 存储在实现上有很大不同,但在概念上没有很大不同(正如您要求的“模型”,我将提供更多详细信息):

    • Git 将数据存储为“对象”(“提交对象” 、“树对象”、“blob 对象”或“标记对象”,存储为由其名称(SHA1 哈希值)唯一标识的文件。这是某种“文件系统哈希表”。在最新版本中,这些对象可以打包为在 .git/objects 目录下的较小文件。我不会再进一步​​,我的理解就到此为止,因为我从来没有发现如何知道比特是如何铺设的。您可以使用以下方法在对象内容中进行漂亮的打印:

      git show -s --format=raw ; # 变更集内容
      git ls-tree ; # 列出树内容
      git show <文件ID> # 斑点内容
      
    • Mercurial 商店每个文件的历史记录分别作为 “revlog(NG)”格式。您可以手动检查 .hg/store/data (revlogNG) 下的文件名。请注意,特殊字符和大写字符是“tilda-下划线编码”。

      您可以使用以下方式列出文件的修订版本:

      hg debugindex .hg/store/data/<文件>.i # hg debugindex <文件>;也可以,但你看到的内部结构较少
      

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

      现在,检查内容:

      hg debugdata .hg/store/data/.i ;
      

      修订历史记录(或多或少您在 hg log 中看到的内容)存储在 .hg/store/00changelog.i 中(使用 hg 检查它debugindex .hg/store/00changelog.i,您将在 nodeid 列中看到与 hg log 中相同的 ID)。要显示 ID 为 XXXX 的原始历史记录条目,请在终端中输入 hg debugdata .hg/store/00changelog.i XXXX。 (看第一行,稍后将用作 YYYY

      树的状态存储在.hg/store/00manifest.i中。清单中对应的 nodeidYYYY

      hg debugdata .hg/store/00manifest.i YYYY
      

      这将显示附加的“文件名+nodeid”列表。让我们选择文件 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 发生冲突(清单(树)和文件(blob)也是如此),这是更不可能的。

  • 在 Git 中,标签是特殊对象,在 Mercurial 中,它只是存储库中文件中的列表(带有一些 规则以了解同一标签的哪个修改副本获胜)。
  • 在 Mercurial 中,默认情况下没有“修改”或“变基”,这是一种设计选择(哲学?),总是追加,从不删除内容,因为它可能会导致并发问题。但通过扩展是可能的。

Quite extended concept differences from Mercurial's official wiki.

Another question from stackoverflow: Git equivalents of most common Mercurial commands?

Comment follow up:

If I resume: "model", "differences", "philosophy behind the differences" and influences on the "workflow". In the differences I can think of, there is:

  • For the workflow, except the lack of staging area, you should be able to stick on your old practices (when to commit, when to branch, when to merge,...).
  • The main difference of philosophy about branches is that Git clones only the specified branch when Mercurial clones all branches (if you want only one branch, it is possible, but it needs configuration).
  • The merge philosophy is not really different. Git can merge two or more heads, but Mercurial can only merge two heads (did you ever merge more?).
  • The philosophy about renames differs greatly and each designer did defend his point of view. As Mercurial tracks renames, merge can be easier. Git tries to guess renames at merge time if you use the strategy "recursive".
  • Storage differs greatly in implementation, but not in concepts (as you asked for "model", I will put more details):

    • Git stores data as "objects" ("commit object", "tree object", "blob object" or "tag object", stored as file uniquely identified by there name which is a SHA1 hash). This is some kind of "filesystem hash table". With recent versions, those objects can be packed to have less small files under the .git/objects directory. I will not go further, my understanding stop here as I never found use to know how bits are laid. You can have a pretty printing in the object's content with:

      git show -s --format=raw <commitid> # changeset content
      git ls-tree <treeid> # list tree content
      git show <fileid> # blob content
      
    • Mercurial stores history of each files individually as "filelog" in the "revlog(NG)" format. You can manually inspect file names under .hg/store/data (revlogNG). Note that special and uppercase characters are "tilda-underscore encoded".

      You can list revisions of a file with:

      hg debugindex .hg/store/data/<file>.i # hg debugindex <file> also works but you see less of internals
      

      You have already noted that the nodeids are not the one in hg log.

      And now, inspect the contents with:

      hg debugdata .hg/store/data/<file>.i <nodeid>
      

      The revision history (more or less what you see with hg log) is stored in .hg/store/00changelog.i (inspect it with hg debugindex .hg/store/00changelog.i, you will see the same IDs as the one in hg log in the nodeid column). To show one raw history entry with id XXXX, type hg debugdata .hg/store/00changelog.i XXXX in a terminal. (look at first line, it will be used later as YYYY)

      The state of the tree is stored in .hg/store/00manifest.i. The corresponding nodeid in the manifest is YYYY.

      hg debugdata .hg/store/00manifest.i YYYY
      

      This will show a list of "filename+nodeid" appended. Let's choose file foo/bar and note the nodeid appended to it and consider it is ZZZZ (line foo/barZZZZ).

      Last step, access to the content of the foo/bar file:

      hg debugdata .hg/store/data/foo/bar.i ZZZZ
      
    • For the differences in philosophy clearly visible from this basic data storage analysis:

      • When Git commits, it make (potentially a lot of) new files (which can be packed later). When Mercurial commits, it appends to existing files.

      • In Git a blobid can collide with a treeid (or commitid or tagid) but that is highly improbable. In Mercurial, a changesetid can collide only with another changesetid (ditto for manifests (tree) and files (blob)) which is even more improbable.

  • In Git, tags are special objects, in Mercurial, it's just a list in a file in the repository (with some rules to know which modified copy of the same tag wins).
  • In Mercurial, there is no "amend" or "rebase" by default and it is a design choice (philosophy?), always append, never remove content, as it can cause concurrency problem. But it is possible with extensions.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文