9

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

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

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

  1. 如果一条路径仅在合并的一个提交链祖先上有内容,我假设内容应该是可见的。那是对的吗?

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

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

4

1 回答 1

8

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

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

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


编辑:啊,让我们更深入地了解 git 模型。

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

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

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

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

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

于 2012-11-05T02:19:24.700 回答