git 将两个存储库 merge 到一个新的存储库中,其中一个应该是一个分支

标签 git merge repository branch visual-sourcesafe

我想将存储库放在一起,但第二个存储库应该进入一个分支

A - B - C - D -  E -  F - G - H Repo1

           A1 - B1 - C1 Repo2

克里特岛新仓库 reponew

git init reponew

为旧存储库 Repo1 添加远程并获取旧存储库

git remote add -f Repo1 ..\..\output\Repo1

将 Repo1/master 中的文件 merge 到 new/master

git merge Repo1/master --allow-unrelated-histories

新的存储库 reponew 如下所示:

A - B - C - D -  E -  F - G - H master

现在我已经在特定提交和 checkout 上创建了一个新分支

git branch branchX 200303b0b215cc0fb2d92f50ffc9d7df8bbaab74
git checkout branchX

为旧存储库 Repo1 添加远程并获取旧存储库

git remote add -f Repo2 ..\..\output\Repo2

将 Repo1/master 中的文件 merge 到 new/master

git merge -Xtheirs Repo2/master --allow-unrelated-histories

现在新的存储库repnew看起来像这样:

                 A1 - B1 - C1 branchX
                                     \
A - B - C  - - - - - - - - - - - - - -
          \
           D - E - - - - - F - G - H master

看起来这是由 merge 日期为现在的 merge 请求引起的

但我希望它看起来像这样:

A - B - C - D - E - - - - - F - G - H master
          \
            - - - A1 - B1 - C1 branchX

最佳答案

在现有历史记录之后“移动”提交的主要方法是使用 rebase 。 merge 只能添加一个新的提交,并将两个历史记录作为父项。
但是rebase不会真正移动commist,而是在指定的onto之后重放它们。因此,如果旧提交上仍然存在引用(分支或标签),它们将在整个提交历史记录中保持可用。

在您的情况下,您希望将 Repo2/master 的历史记录重新设置为提交 C

所以解决办法是:

git branch branchX --no-track Repo2/master
git rebase -Xtheirs 200303b0b215cc0fb2d92f50ffc9d7df8bbaab74 branchX

你应该得到你想要的结果。


@torek建议,还有filter-branchfilter-branch 允许您通过在每个重写的提交上应用过滤器来重写提交历史记录。它主要用于删除错误提交的敏感数据(例如密码)、从历史记录中删除大文件或更改存储库的根文件夹。 filter-branch 的优点是它还会移动标签。
它还会过滤带有空消息的提交。

使用filter-branch,有一个--parent-filter,允许您在过滤时更改提交的父级。
它将过滤列出的所有引用,因此要移动标签,我们必须列出当前 branchX 中的所有标签:git tag --mergedbranchX,然后按原样过滤它们与 --tag-name-filter cat

所以命令将是:

git branch branchX --no-track Repo2/master
git filter-branch \
    --parent-filter 'test $GIT_COMMIT = <FULL-commit-id-of-A1> && echo "-p 200303b0b215cc0fb2d92f50ffc9d7df8bbaab74" || cat' \
    --tag-name-filter cat \
    -- branchX $(git tag --merged branchX)

然后您将获得重写的历史记录,但仍然是旧的历史记录,并且引用前缀为 refs/original/

如果没问题,可以删除原来的引用(rm -rf .git/refs/original/),否则可以恢复它们(cp -r .git/refs/原始/refs .git && rm -rf .git/refs/original/)。

关于git 将两个存储库 merge 到一个新的存储库中,其中一个应该是一个分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46114139/

相关文章:

Git clone from remote ssh repository - 在执行克隆命令之前更改远程网络上的机器

java - 如何将SVN分支合并到主干?

python - 合并给定列的交集上的两个数据框

linux - 有没有办法在特定时间自动提交 git 中的更改

git - 多容器、多存储库项目中的部署文件放在哪里?

bash - 使用 xargs 显示 git 别名中的命令

git - 由于权限问题,无法将所有文件添加到 git

git - 目录变成子模块后 merge

java - Spring - 将存储库 Autowiring 到服务中时出现 NoSuchBeanDefinitionException

java - 如何在eclipse中同步使用TortoiseSVN 1.8导入的项目?