简体   繁体   English

git将没有共同祖先的多个仓库中的工作合并到新仓库中

[英]git merge work from multiple repos with no common ancestor into new repo

I have a few repos that I'd like to merge into a new master repo, and all of these repos have unique histories (absolutely no common commits among them). 我有一些仓库,我想合并到一个新的主仓库中,所有这些仓库都有独特的历史记录(在它们之间绝对没有共同的提交)。 I've created the new master repo, created a branch on each of the other repos, and pushed each branch to the master repo. 我已经创建了新的主存储库,在其他每个存储库上都创建了一个分支,并将每个分支推送到主存储库。 Now in master_repo, merging each branch into the master branch produces no conflicts using either git merge -s ours and also with a simple git merge (I've tried both from scratch)...but I'm failing with these attempts to merge folders from other branches into the master branch. 现在在master_repo中,使用git merge -s ours以及简单的git merge(将我从头开始都尝试过),将每个分支合并到master分支中不会产生任何冲突...但是这些合并尝试都失败了文件夹从其他分支转移到master分支。 I believe part of the problem is that there are no common ancestor commits. 我认为部分问题是没有共同的祖先承诺。 I can reproduce the problem as follows: 我可以重现以下问题:

Directory structure set up within test_merge: master_repo (with folder 01) other_repoA (with folder 03) other_repoB (with folders 01 and 09) 在test_merge中设置的目录结构:master_repo(带有文件夹01)other_repoA(带有文件夹03)other_repoB(带有文件夹01和09)

and then in Cygwin terminal ("..." = cropped terminal messages): 然后在Cygwin终端中(“ ...” =裁剪的终端消息):

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

ADDING FILE AND COMMITING ON master BRANCH OF master_repo 在master_repo的master分支上添加文件并进行通信

$ 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

ADDING FILE, COMMITING ON master BRANCH OF other_repoA, ADDING NEW BRANCH, AND PUSHING NEW BRANCH TO master_repo 添加文件,与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

ADDING FILE, COMMITING ON master BRANCH OF other_repoB, ADDING NEW BRANCH, AND PUSHING NEW BRANCH TO master_repo 添加文件,在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

A LOOK AT master_repo 看看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

MERGE ATTEMPT: Note that content in branches A and B seem to get ignored 合并尝试:请注意,分支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

The end result I wanted to see was folders 03 and 09 added to the master_repo and " from other_repoB" appended to 01/file01. 我希望看到的最终结果是将文件夹03和09添加到master_repo,并将“ from other_repoB”附加到01 / file01。 Is what I'm looking for even possible using git (and NOT manually copying anything)? 我正在寻找甚至可以使用git(而不是手动复制任何东西)的东西吗?

You need to add some read-tree work to go with the -s ours null merge: 您需要添加一些read-tree工作来进行-s ours null合并:

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 read-tree docs git read-tree文档

Read-tree is the core of checkout and merge and many others, anything you want to do that combines trees and index and often some worktree updates, you build this way. 读取树是签出和合并的核心,还有许多其他事情,您想要做的一切都将树和索引结合在一起,通常还需要对一些工作树进行更新,您可以通过这种方式来构建。

I found my answer in documentation here: 我在这里的文档中找到了答案:

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

which explains about the -Xours option that... 解释了有关-Xours选项的信息...

all the other non-conflicting changes on that branch are merged successfully in. 该分支上的所有其他非冲突更改都已成功合并。

as well as what -s ours does, which is a little different... 以及-s ours所作所为,这有点不同...

If you want to do something like this but not have Git even try to merge changes from the other side in, there is a more draconian option, which is the “ours” merge strategy. 如果您想做这样的事情,但是甚至连Git都没有尝试合并另一侧的更改,则有一个更严厉的选择,这就是“我们的”合并策略。 This is different from the “ours” recursive merge option. 这与“我们的”递归合并选项不同。

This will basically do a fake merge. 这基本上将进行伪合并。 It will record a new merge commit with both branches as parents, but it will not even look at the branch you're merging in. It will simply record as the result of the merge the exact code in your current branch. 它将记录两个分支都作为父级的新合并提交,但它甚至不会查看您要合并的分支。它将简单地记录合并的结果作为当前分支中的确切代码。

What I was looking for was the -Xours option. 我正在寻找的是-Xours选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM