Git 将来自多个没有共同祖先的存储库的工作合并到新的存储库中



我有一些存储库,我想将其合并到一个新的主存储库中,并且所有这些存储库都有独特的历史记录(它们之间绝对没有共同的提交)。 我创建了一个新的主存储库,在其他每个存储库上创建了一个分支,并将每个分支推送到主存储库。 现在在 master_repo 中,使用 git merge -s our 和简单的 git 合并不会产生冲突(我从头开始尝试了两者)......但是我尝试将其他分支中的文件夹合并到主分支中失败了。 我认为部分问题在于没有共同的祖先提交。 我可以重现该问题,如下所示:

test_merge内设置的目录结构:master_repo(带文件夹 01)other_repoA(带文件夹 03)other_repoB(包含文件夹 01 和 09)

然后在 Cygwin 终端中("..." = 裁剪的终端消息):

$ cd master_repo/
$ git init
Initialized empty Git repository in .../test_merge/master_repo/.git/

在master_repo的主分支上添加文件和提交

$ echo "text in file01" > 01/file01
$ git add *
warning: LF will be replaced by CRLF in 01/file01.
The file will have its original line endings in your working directory.
$ git commit -m "master_repo: first commit"
[master (root-commit) ...blah, blah...
1 file changed, 1 insertion(+)...blah, blah

添加文件,在other_repoA的主分支上提交,添加新分支,并将新分支推送到

master_repo
$ cd ../other_repoA
$ git init
Initialized empty Git repository...blah,blah
$ echo "text in file03" > 03/file03
$ git add *
...
$ git commit -m "other_repoA: first commit"
...
$ git checkout -b branchA
...
$ git status
On branch branchA
nothing to commit, working directory clean
$ git push ../master_repo branchA
To ../master_repo
 * [new branch]      branchA -> branchA

添加文件,在other_repoB的主分支上提交,添加新分支,并将新分支推送到

master_repo
$ cd ../other_repoB
$ git init
...
$ echo "text in file01 from other_repoB" > 01/file01
$ echo "text in file09 from other_repoB" > 09/file09
$ git add *
$ git commit -m "other_repoB: first commit"
...
$ git checkout -b branchB
...
$ git status
On branch branchB
nothing to commit, working directory clean
$ git push ../master_repo branchB
To ../master_repo
 * [new branch]      branchB -> branchB

看看

master_repo
$ cd ../master_repo
$ git status
On branch master
nothing to commit, working directory clean
$ git branch
  branchA
  branchB
* master
$ ls
01
$ git checkout branchA
Switched to branch 'branchA'
$ ls
03
$ git checkout branchB
Switched to branch 'branchB'
$ ls
01  09

合并尝试:请注意,分支 A 和 B 中的内容似乎被忽略

$ git checkout master
Switched to branch 'master'
$ git merge -s ours branchA
$ ls
01
$ git merge -s ours branchB
Merge made by the 'ours' strategy.
$ ls
01
$ cat 01/file01
text in file01
$ git checkout branchB
Switched to branch 'branchB'
$ ls
01  09
$ cat 01/file01
text in file01 from other_repoB

我想看到的最终结果是文件夹 03 和 09 添加到master_repo中,并将"from other_repoB"附加到 01/file01。 我正在寻找的东西甚至可以使用 git(而不是手动复制任何东西)吗?

您需要

添加一些read-tree工作才能使用-s ours空合并:

git merge -s ours --no-commit branchA    # null `-s ours` for `branchA` parent
git read-tree -u --prefix= branchA       # add the branchA tree at the project root
git commit

Git 读取树文档

读取树是结帐和合并的核心,以及许多其他核心,任何你想做的结合树和索引以及通常的一些工作树更新,你都是这样构建的。

我在文档中找到了答案:

https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#Other-Types-of-Merges

这解释了-Xours选项...

该分支上的所有其他非冲突更改将成功合并。

以及-s ours做什么,这有点不同......

如果你想做这样的事情,但 Git 甚至没有尝试合并来自另一边的更改,有一个更严厉的选择,即"我们的"合并策略。这与"我们的"递归合并选项不同。

这基本上会做一个假合并。它将记录一个新的合并提交,并将两个分支作为父分支,但它甚至不会查看您要合并的分支。它将简单地记录当前分支中的确切代码作为合并的结果。

我正在寻找的是-Xours选择。

最新更新