【问题标题】:What are the merge semantics of git fast-import streams?git fast-import 流的合并语义是什么?
【发布时间】:2014-07-14 21:51:00
【问题描述】:

我编写并维护了一个名为 reposurgeon 的开源工具,它可以编辑版本控制存储库历史记录,并可用于在 VCS 之间移动项目历史记录。最近我提供了对读取 Subversion 转储文件和 repos 的全面支持。但是有一件事 reposurgeon 还没有做得很好,那就是通过复制到 git 样式的 DAG 合并来翻译 Subversion 分支合并。

为了使这部分正确,我需要比我更好地理解 git fast-import 流中合并提交的语义。我的问题是关于合并提交后应该显示哪个版本的内容。

当然,合并提交后附加的文件修改使它们的内容在那里可见。我的问题是关于提交触及的路径。

  1. 如果一个路径只有一个提交链上的内容,我认为内容应该是可见的。对吗?

  2. 如果一条路径在合并的多个祖先链中包含多个提交链中的内容,哪个版本将可见?

  3. 如果一个文件沿某些路径被删除到合并,什么规则预测它何时会在合并修订中被删除?

【问题讨论】:

    标签: git git-fast-import


    【解决方案1】:

    如果我理解您的问题,您想知道在将提交内容流式传输到其中时,快速导入可以让您使用哪些快捷方式。

    据我阅读git/fast-import.c 和手册页可知,快速导入会初始化树,以便从“from”命令中提供的树中进行新的提交。 "filemodify" 和朋友从那个状态开始构建新树,并在最后提交。

    在遇到“合并”命令时,快速导入命令似乎根本不会改变树;如果您想包含除第一个以外的父项的更改,则需要准确指定要引入的文件。不过,您可以使用标记或对象哈希来命名“filemodify”的其他分支文件。


    edit:啊,让我们深入了解 git 模型。

    在 git 中,提交指向一棵树,该树代表被跟踪的目录层次结构的全部内容,就像提交时一样。提交不携带任何关于他们与父母有何不同的信息;理论上,如果需要,您可以通过比较这些树来重建差异。

    合并提交与非合并提交的区别仅在于它有两个或多个父级。它仍然有一棵树,准确记录了执行合并后版本中的内容。它仍然没有记录任何关于其作者如何将父母组合成合并版本的信息。像 git loggit diff 这样的 git "porcelain" 命令会神奇地重建对所发生事件的有用描述。

    从概念上讲,要创建一个新的提交对象,您需要描述路径到该提交中文件内容的完整映射。 (很多聪明之处在于让它变得高效和简单,而不是糟糕。)

    git fast-import 命令为常见情况提供了一个快捷方式:通常,您要从中导出的 VCS 可以告诉您此提交是如何形成的,与同一分支上最近一次提交的某种差异。在这种情况下,您可以有效地将 diff 编码为 fast-import 的流格式,以便更简单、更快速地导入。

    但您必须记住,这只是从头开始重新构建整个树的捷径。

    【讨论】:

    • 呃,如果快速导入没有改变树以响应合并命令,那么合并命令意味着什么
    • 在快速导入中,它只是将第二个(或第三个、第四个……)父提交添加到您当前正在构建的提交对象中。
    • 但是,如果添加父提交意味着不会导致在合并修订时对树进行更改?该父链接携带什么信息?
    • 合并提交与任何其他提交一样,除了有多个父提交;与任何其他提交一样,它指的是表示提交后存储库中文件状态的树;在合并的情况下,它是保存任何自动或手动合并父级结果的树。对于fast-import,您可以使用filemodify (M) 命令输入该信息。如果您使用from + merge,那么您可以指定相对于from 祖先的更改;如果您使用merge + merge,那么您从一棵空树开始,并且必须提供所有文件的状态。
    • 我现在要为 git 快速导入页面编写补丁。这需要记录在案,以免其他人像我一样误入歧途。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 2018-08-07
    • 2023-02-11
    • 2011-11-08
    • 1970-01-01
    • 2017-02-12
    相关资源
    最近更新 更多