我编写并维护了一个名为reposurgeon的开源工具,它编辑版本控制存储库历史记录,可用于在VCS之间移动项目历史记录。最近我发送完全支持读取Subversion转储文件和repos。但是有一件事reposurgeon还没有做得很好,那就是通过复制到git风格的DAG合并来翻译Subversion分支合并。
为了使这一部分正确,我需要比git更快地理解git快速导入流中的合并提交的语义。我的问题是关于合并提交后应该看到哪个版本的内容。
当然,附加合并提交的文件修改使其内容可见。我的问题是关于提交所触及的路径 。
如果一个路径只在祖先合并的一个提交链上有内容,我认为该内容应该是可见的。这是对的吗?
如果一个路径在合并的祖先的多个提交链中有内容,哪个版本可见?
如果在合并的某些路径中删除了某个文件,那么什么规则会预测合并修订中何时删除该文件?
答案 0 :(得分:6)
如果我理解了您的问题,那么您想知道快速导入的快捷方式是什么,可以在将提交内容流式传输到其中时使用。
据我在阅读git/fast-import.c
和手册页时可以看出,fast-import从“from”命令中提供的树初始化树以进行新提交。 “filemodify”和朋友从该州开始构建将在最后提交的新树。
遇到“merge”命令时,fast-import命令似乎根本不会更改树;如果要包含除第一个之外的父项的更改,则需要准确指定要引入的文件。您可以使用标记或对象哈希来命名“filemodify”的其他分支文件。
编辑:啊,让我们深入了解git模型。
在git中,提交指向一个树,该树表示正在跟踪的目录层次结构的整个内容,就像它在提交时一样。提交者不会提供有关他们与父母有何不同的任何信息;理论是你可以通过比较这些树来重建差异。
合并提交与非合并的区别仅在于它有两个或更多个父项。它仍然有一棵树,准确记录执行合并所产生的版本中的内容。它仍然没有记录其作者如何将父母合并为合并版本。像git log
和git diff
这样的git“瓷器”命令可以重现对所发生事件的有用描述。
从概念上讲,要创建新的提交对象,您需要描述路径到该提交中的文件内容的完整映射。 (很多聪明才能使这种有效而简单而非可怕。)
git fast-import
命令为常见情况提供了一个快捷方式:通常,您从中导出的VCS可以告诉您如何将此提交形成为同一分支上最近提交的某种差异。在这种情况下,您可以有效地将差异编码为快速导入的流格式,以便更简单,更快速地导入。
但是你必须记住它只是从头开始重构整个树的捷径。