将两个存储库合并为一个,两个都有分支

问题描述 投票:2回答:1

我有两个独立的存储库 - 后端和前端。我想把它们结合起来,所以我想的是:

git clone [email protected]:backend.git
git clone [email protected]:frontend.git
cd frontend
mkdir frontend
git mv !(frontend) frontend
git commit -a -S -m "Moving frontend into its own subdirectory"

cd ../backend
git remote add frontend ../frontend
git fetch frontend
git checkout -b feature/merge-front-back
git merge -S --allow-unrelated-histories frontend/master
git push origin feature/merge-front-back
git remote rm frontend

...现在,在验证合并之后:

git checkout master
git merge feature/merge-front-back

所以我的一个问题是:这是好计划吗?你看到任何缺陷或更好的方式吗?

2问题..前端分支怎么样?其中大部分我现在都不需要(也许永远不会),但是希望将来可以选择与它们合并。我是否需要重复上述过程,但是对于每个前端分支,将前端/分支/功能1合并到后端/分支/前后合并功能1,依此类推?

(我假设合并到包含前端目录和历史记录的“新”主分支时后端分支没有问题)

git bitbucket git-merge branching-and-merging
1个回答
4
投票

这是好计划吗?你看到任何缺陷或更好的方式吗?

通过“这是一个好的计划”,我认为你的意思是“这组命令是做我打算做的事情的好方法”。在这方面,还有其他方法,但我不会说一个更好或更坏。

如果你想让最终的仓库拥有前端分支,那么就会缺少一个步骤;我将在下面解决。

更一般地说 - 我将提供警告,几乎总是任何人试图通过将多个项目组合成一个回购来解决的问题,被处理组合结构的更大问题所取代。这些是逻辑上独立的项目是你必须要确定的,但作为一项规则,我已经看到将repos组合在一起往往是一个错误的方向。

但如果你认为它们应该是一个回购,那么那些命令(一目了然)就像任何一样好。我猜这个显而易见的问题是,为什么不试试呢?唯一可以损坏的是新创建的克隆。

前端分支怎么样?

当你来自fetchfrontend时,你的组合回购将获得每个frontend分支的“远程跟踪参考”。所以对于frontend分支master你会得到remotes/frontend/master

但是,当你remove遥控器时,这些将被删除。对master而言并不重要(因为你已经将frontend/master合并到了master)。对于其他分支,你需要告诉git保持对它们的引用 - 当然,如果它保留的引用是一个分支将是方便的。一种方法是

git fetch frontend refs/heads/*:refs/heads/frontend/*

在这里,您要为分支创建frontend命名空间,并将frontend中的所有分支添加到该命名空间中。 (只要您在后端仓库中没有名为frontend的分支或已经存在的frontend分支命名空间,就可以了。如果由于某种原因确实有其中一个,则必须使用其他名称为命名空间。)

这些新创建的引用在refs/heads下,因此它们将被视为正确的分支(而不是远程跟踪引用),并且在删除原点时不会删除它们。从那时起,它们与您的后端分支没有什么不同。

在将来将frontend分支合并到master时可能会遇到问题,或者您可能不会。 git将尝试解决所有文件移动造成的冲突;但请记住,git并不能真正跟踪文件移动 - 而是在事后以启发式方式重建它们 - 所以这种机制并不完美。

如果你担心这样的问题 - 或者如果你做了一些测试合并并发现会有不可接受的问题 - 那么一个选择就是重写frontend/*分支的历史,看起来就像文件“总是在”下一个frontend/文件夹。如果我这样做,我会在组合存储库之前这样做;即克隆frontend后,我会重写克隆的历史,而不是创建一个新的提交来移动文件。

(你建议为每个分支重复你在master上执行的程序类型。虽然你可以测试它,但我不相信它会运作良好。问题是虽然master被处理为无关历史的合并,其他frontend分支的后续合并将不会。为了使这些合并正常工作,git仍然必须正确解释文件移动 - 实际上必须在合并的两个“边”正确解释它们。)

如果您选择重写frontend历史记录,最直接的方法是使用git filter-branch--tree-filter脚本将文件移动到子目录。有关详细信息,请参阅git filter-branch文档。 (https://git-scm.com/docs/git-filter-branch

© www.soinside.com 2019 - 2024. All rights reserved.