git 合并已用共享文件重写的分支

git merging branches that have been rewritten with shared files

大约一年前从master分支出来,分支变成了long-运行第二个项目。在此期间,相同的文件在每个分支中都经历了近乎完全的重写。我现在已经将分支中的代码库移动到它自己的文件夹中,但是在合并时,两个独立项目共同使用的文件存在一年的冲突。

最好的解决方案是重写我的分支的整个历史以使用不同的文件夹吗?我如何将这两个代码库合并到不同的文件夹中?

Is the best solution to rewrite the entire history of my branch to use a different folder?

这取决于此时它们在逻辑上是否是不同的文件。如果它们在逻辑上是单个文件——如果对一个项目的更改在最坏的情况下不会损害另一个项目的使用,尤其是如果相同的更改通常对两个项目都有好处——那么你最好在维护方面合并它们。但是,如果单个文件不再为两个主文件服务,那么您将不得不将它们拆分 - 无论是像上面考虑的那样简单地 renaming/moving 一个,还是在有原因的情况下通过更复杂的重构(例如,可能是某些部分)该文件仍然很常见)。

所以这是您必须确定的事情。如果您确实希望将它们分开,那么重写一个项目的历史记录以重新定位文件是一种选择。它在概念上很简单,所以这是优点。不利的一面是,它可能会破坏项目的历史版本(因为它可能会在它期望的文件所在的位置找到其他项目的文件...除非您进行更彻底的重写,将每个历史版本更新为 know 文件已移动),如果共享回购协议,则所有用户都必须协调更新到新的历史记录。

现在,如果整个项目的代码如此不相关以至于将每个代码库放在一个单独的文件夹中是有意义的,那么您可能需要考虑将它们保存在单独的存储库中。出于某种原因 "monorepos" 获得了一些人气,但实际上它并不是 git 的最佳用途。要使用该工具的条款,您可以让每个 repo 成为一个项目的主页(并且,如果有共享组件,最好将其移至第三个 repo 并使用 git 子模块或构建工具将其包含为每个项目的依赖项)。

但是,如果您仍然决定让这两个项目共享一个历史记录,并在共享提交中共存于不同的文件夹中,则有几种方法可以实现。

正如您所注意到的,您可以尝试重写分支的历史记录。我不确定这是否会解决问题,因为在您创建分支之前存在的任何这些文件在分支的第一次提交中仍将被观察为 "moved" 。 (除非您还将它移动到分支创建之前的共享历史记录中,在这种情况下,它将在 other 分支的下一次提交中被视为 "moved back" ... )

因此,您可能只想调整合并的工作方式。将文件移动到各自分支尖端的未来路径后,您将启动合并但不提交;使工作树进入所需状态;然后提交。

假设有一些文件你确实打算合并,那么你可以正常开始合并,因为冲突会阻止提交。然后作为 "conflict resolution" 的一部分,您将整理出路径。

git checkout HEAD -- project-1-path
git checkout project-2-branch -- project-2-path

(其中 project-1-pathproject-2-path 是您将相关文件的相应版本移动到的文件位置,在合并之前对每个分支的最后一次提交中)。