简体   繁体   English

Git - 合并两个具有共同祖先的存储库

[英]Git - merge two repositories with common ancestor

Let's say I used to have a repository Z and created two repositories (A and B) based on it.假设我曾经有一个存储库 Z 并基于它创建了两个存储库(A 和 B)。

I made them mutually exclusive.我让它们相互排斥。 What I mean is files in A should not be in B and viceversa.我的意思是 A 中的文件不应该在 B 中,反之亦然。 So, I deleted the some files in A and also files in B.所以,我删除了 A 中的一些文件和 B 中的文件。

These two repositories kept growing over time.这两个存储库随着时间的推移不断增长。

Now, due to some management decision, I need them back as a single repository.现在,由于某些管理决策,我需要将它们作为单个存储库返回。 I tried doing a merge as indicated in How to use the subtree merge strategy , but it gives me too many conflicts and the merge itself was very dirty.我尝试按照如何使用子树合并策略中的说明进行合并,但它给我带来了太多冲突,并且合并本身非常脏。 I understand this is an uncommon and difficult task.我理解这是一项不寻常且艰巨的任务。

Have any of you faced the same problem, how did you fix it?大家有没有遇到过同样的问题,你们是怎么解决的?

I have my doubts about this being a good idea, but it sounds like it doesn't really matter whether it is or not.我怀疑这是一个好主意,但听起来它是否真的无关紧要。

So you had a single repo with, I'll assume, two projects in it.所以你有一个单一的回购,我假设里面有两个项目。 They shared a history, and it seems you need to get back to that state - one master branch with all the files.他们共享了一段历史,看来你需要回到那个状态——一个包含所有文件的主分支。

You've apparently gotten as far as bringing all the objects into one repo.您显然已经将所有对象都带入了一个存储库。 For example, perhaps you added one repo as a remote of the other, and fetched its master ref;例如,也许您添加了一个 repo 作为另一个 repo 的远程,并获取了它的主引用; so let's say you have所以假设你有

A -- B -- C -- X1 -- X2 -- X3 <--(master)
           \
            Y1 -- Y2 -- Y3 <--(repoB/master)

You try你试试

git checkout master
git merge repoB/master

and you get conflicts and other messiness, and probably understanding that messiness will help understand what to do instead.并且您会遇到冲突和其他混乱,并且可能理解混乱将有助于了解该怎么做。 The conflicts could be as simple as "file was deleted here and modified there", which is pretty easy to resolve, but other things can be going on as well.冲突可能就像“文件在此处删除并在此处修改”一样简单,这很容易解决,但其他事情也可能发生。

For example, if you were splitting up two projects, then you might have moved a bunch of stuff from what was a project sub-directory up to the work tree root.例如,如果您要拆分两个项目,那么您可能已经将一堆东西从项目子目录移动到工作树根目录。 Or you might have created a file in one repo, with the same path/name as an existing file in the other repo.或者您可能在一个 repo 中创建了一个文件,其路径/名称与另一个 repo 中的现有文件相同。 Or whatever.或者随便。

So the first thing I would do is to make sure each repo's worktree is laid out as a subset of the combined worktree you want going forward.因此,我要做的第一件事是确保每个 repo 的工作树都被布置为您想要前进的组合工作树的子集。 If it's already the case - ie you didn't move the files around after splitting the repos, there no path/filename that exists in both repos, and the desired worktree is just what you'd get by cd ing to one repo's worktree and cp -R ing the other repo's worktree - then you can skip ahead past this step.如果已经是这种情况 - 即您在拆分存储库后没有移动文件,则两个存储库中都不存在路径/文件名,并且所需的工作树正是您通过cd到一个存储库的工作树获得的cp -R其他 repo 的工作树 - 然后你可以跳过这一步。

But otherwise, you could但否则,你可以

git checkout master

and then mv files as needed so that you have a subset of the desired worktree, and commit.然后根据需要mv文件,以便您拥有所需工作树的子集,然后提交。 Then然后

git checkout repoB/master
git checkout -b repoB

and again mv things around as needed and commit.并根据需要再次mv周围的东西并提交。

A -- B -- C -- X1 -- X2 -- X3 -- X <--(master)
           \
            Y1 -- Y2 -- Y3 -- Y <--(repoB)

You could get by without this, but it gives us simpler options for the next step than what we would have otherwise.没有这个你也可以过得去,但它为我们提供了比其他方式更简单的下一步选择。

Next we probably want to start a merge.接下来我们可能想要开始合并。 We don't want the default merge result, which means we're creating what might be called an "evil" merge;我们不想要默认的合并结果,这意味着我们正在创建可能被称为“邪恶”合并的东西; but in my view it's not as bad since the merge would, by default, conflict - so in a sense, there is no default merge result.但在我看来,这不是那么糟糕,因为合并将,默认情况下,冲突-所以从某种意义上讲,没有默认的合并结果。

Anyway, we want to put git in a "merge-in-progress" state, but its default merge algorithm isn't much use here;无论如何,我们想让git处于“merge-in-progress”状态,但它的默认合并算法在这里用处不大; so所以

git checkout master
git merge -s ours --no-commit repob

Now we need to add the files from repob , which will work smoothly because none of them are at the same path as a file we already have.现在我们需要添加来自repob的文件,这将顺利工作,因为它们都与我们已有的文件不在同一路径。

git checkout repob -- .

Verify that the worktree now looks right.验证工作树现在看起来是否正确。 Then然后

git commit

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

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