git快速导入流的合并语义是什么?

ESR*_*ESR 7 git git-fast-import

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

为了使这一部分正确,我需要比git更快地理解git快速导入流中的合并提交的语义.我的问题是关于合并提交后应该看到哪个版本的内容.

当然,附加合并提交的文件修改使其内容可见.我的问题是关于提交没有触及的路径.

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

  2. 如果路径在合并中具有多个祖先的提交链中的内容,那么哪个版本可见?

  3. 如果沿着合并的某些路径删除文件,那么什么规则会预测合并修订中何时删除它?

Jam*_*arp 7

如果我理解你的问题,你就会想知道快速导入的快捷方式允许你在将提交内容流式传输时使用哪些快捷方式.

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

遇到"merge"命令时,fast-import命令似乎根本不会更改树; 如果要包含除第一个之外的父项的更改,则需要准确指定要引入的文件.您可以使用标记或对象哈希来命名"filemodify"的其他分支文件.


编辑:啊,让我们深入了解git模型.

在git中,提交指向一个树,该树表示正在跟踪的目录层次结构的整个内容,就像它在提交时一样.提交者不会提供有关他们与父母有何不同的任何信息; 理论是你可以通过比较这些树来重建差异.

合并提交与非合并的区别仅在于它具有两个或更多个父项.它仍然有一棵树,准确记录执行合并所产生的版本中的内容.它仍然没有记录其作者如何将父母合并为合并版本.git"瓷器"命令喜欢git loggit diff做魔术来重建对所发生事件的有用描述.

从概念上讲,要创建新的提交对象,您需要描述路径到该提交中的文件内容的完整映射.(很多聪明才能使这种有效而简单而非可怕.)

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

但是你必须记住它只是从头开始重构整个树的捷径.

  • 合并提交就像任何其他提交一样,除了拥有多个父项; 像任何其他提交一样,它引用一个树,表示提交后repo中文件的状态; 在合并的情况下,它是保存父母的任何自动或手动合并结果的树.在"快速导入"的情况下,您可以使用`filemodify`(`M`)命令输入该信息.如果使用`from` +`merge`,那么你可以指定相对于`from`祖先的变化; 如果你使用`merge` +`merge`然后你从一个空树开始,必须提供所有文件的状态. (3认同)
  • 在快速导入中,它只是将第二个(或第三个,第四个,......)父提交添加到您当前正在构建的提交对象中. (2认同)