git - 将两个存储库合二为一,都有分支

标签 git bitbucket git-merge branching-and-merging

我有两个独立的存储库 - 后端和前端。我想将它们结合起来,所以我正在考虑类似的事情:

git clone git@server.com:backend.git
git clone git@server.com: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

...现在,在验证 merge 后:
git checkout master
git merge feature/merge-front-back

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

还有 2 个问题.. 前端分支呢?
他们中的大多数我现在不需要(也许永远不需要),但希望将来可以选择与他们 merge 。
我是否需要重复上述过程,但对于每个前端分支分别将前端/分支/feature1 merge 到后端/分支/front-back-merge-feature1,等等?

(我假设后端分支在 merge 到包含前端目录和历史记录的"new"主分支时不会出现问题)

最佳答案

is it good plan? do you see any flaws or better way?



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

如果您希望最终存储库具有前端分支,则缺少一个步骤;我将在下面解决这个问题。

更一般地说 - 我将提供警告,几乎总是有人试图通过将多个项目组合到一个 repo 来解决的任何问题,都会被处理组合结构的更大问题所取代。这些是否是逻辑上独立的项目是您必须确定的,但通常,我看到 merge repos 往往是朝着错误的方向迈进。

但是,如果您坚信它们应该是一个 repo,那么这些命令(乍一看)似乎和任何命令一样好。我想显而易见的问题是,为什么不试试呢?唯一可以损坏的是新创建的克隆。

what about frontend branches?



当你fetch来自 frontend ,您的 merge repo 将为每个 frontend 获得“远程跟踪引用”分支机构。所以对于 frontend分公司master你会得到remotes/frontend/master .

但是,当您 remove 时,这些将被删除。 Remote 。对于 master这不一定重要(因为您已将 frontend/master merge 到 master 中)。对于其他分支,您需要告诉 git 为它们保留一个 ref - 当然,如果它保留的 ref 是一个分支,那将很方便。一种方法是
git fetch frontend refs/heads/*:refs/heads/frontend/*

在这里,您正在创建 frontend分支的命名空间,并添加来自 frontend 的所有分支进入那个命名空间。 (只要您在后端存储库中还没有名为 frontend 的分支或已经存在的 frontend 分支命名空间,就可以了。如果您出于某种原因确实拥有其中一个,则必须为命名空间使用不同的名称。)

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

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

如果您担心此类问题 - 或者如果您进行了一些测试 merge 并发现存在 Not Acceptable 问题级别 - 那么您可以选择重写 frontend/* 的历史记录。分支看起来像 frontend/ 下的文件“一直是”文件夹。如果我要这样做,我会在 merge 存储库之前这样做;即克隆后立即frontend我会重写克隆的历史,而不是创建一个新的提交来移动文件。

(您建议对每个分支重复您在 master 上执行的过程类型。我不相信这会很好,尽管您可以对其进行测试。问题是虽然 master 正在作为 merge 处理对于不相关的历史,来自其他 frontend 分支的后续 merge 将不会。为了使这些 merge 正常工作,git 仍然必须正确解释文件移动 - 实际上必须在 merge 。)

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

关于git - 将两个存储库合二为一,都有分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52115444/

相关文章:

git - 无法使用 Sourcetree 克隆存储库

git - 在 git 中,如何增加 merge 的上下文?

git - 在 git 中以相反的父顺序创建 merge 提交

git - 使用 protected 分支在本地解决 merge 请求

git - 无法从 linode 服务器克隆托管的 git 存储库

git - 如何 git stash pop 在当前分支上创建的最后一个存储?

git - 与 IntelliJ merge 提交

git - 为什么 git fetch 不下载任何东西?

git - 恢复到 bitbucket 中之前的更改

reactjs - Visual Studio Code [eslint] 在 windows 上删除 'CR' [prettier/prettier]