使用git将两个目录与​​公共父级合并(但不同的SHA1)

HNy*_*ard 4 git merge git-merge

在我们的项目中,有人拿了代码的副本.他们在他们的目录中启动了一个新的git存储库并继续他们的工作.与此同时,我们主要项目库的工作也在继续.我们现在剩下两个没有共同SHA1的git存储库.

A --- B --- C --- D
      |
      | Copy of code to new directory
      |
      E --- F --- G
Run Code Online (Sandbox Code Playgroud)

B和E是完全相同的文件,文件夹等.

我们的目标是使用Git将变更F和G合并到主分支(目前在D)

Die*_*Epp 7

首先,我要重新绘制图表.

A --- B --- C --- D  master

         E --- F --- G  copy

让我们先把这两个放在同一个回购中.没有特殊的步骤,你只需要git fetch进入同一个存储库.

然后你创建一个移植.编辑.git/info/grafts...

<E-sha1> <B-sha1>
Run Code Online (Sandbox Code Playgroud)

然后运行git filter-branch使其永久化.

git filter-branch --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

这将创造一个新的历史,"正确"的历史:

A --- B --- C --- D  master
        \
         E --- F --- G  copy

之后,你可以合并.

演示在行动中

我创建了两个与图表匹配的存储库,从提交B复制到提交E.

  • E有SHA-1 3aa6b69127d20ac42746c39be3c273a9d80fb706
  • B有SHA-1 95b0fc836dbea7eaa0d043390df841d184af7cd5
$ git init
$ git remote add master ../gittest
$ git remote add copy ../gittest2
$ git fetch master
remote: Counting objects: 12, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 12 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (12/12), done.
From ../gittest
 * [new branch]      master     -> master/master
$ git checkout -b master master/master
Branch master set up to track remote branch master from master.
Already on 'master'
$ git fetch copy
warning: no common commits
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 9 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (9/9), done.
From ../gittest2
 * [new branch]      master     -> copy/master
$ git log --format=oneline copy/master | tail -n 1
3aa6b69127d20ac42746c39be3c273a9d80fb706 E
$ git log --format=oneline master/master
1532332fe705931babe9db04c8d84051867b52c9 D
90903c0ac8dc26649b875ee00ea39bfd7571b1fb C
95b0fc836dbea7eaa0d043390df841d184af7cd5 B
e9de90c82a32041cff3a19f8e40d4358bc4ec2ca Commit A
$ git log --format=oneline master/master
bec0e7af9374e4c57cb87f3fd5b2fb2b6a3f431b G
a61e01d096e81c36bcc450afd98ca94cff909622 F
3aa6b69127d20ac42746c39be3c273a9d80fb706 E

如果你现在合并会发生什么?

我遇到了合并冲突,我宁愿自动解决.

$ git merge copy/master
Auto-merging test.txt
CONFLICT (add/add): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.

移植中的移植物

$ echo 3aa6b69127d20ac42746c39be3c273a9d80fb706 \
    95b0fc836dbea7eaa0d043390df841d184af7cd5 > .git/info/grafts
$ git filter-branch --tag-name-filter cat -- --all
Rewrite bec0e7af9374e4c57cb87f3fd5b2fb2b6a3f431b (7/7)
WARNING: Ref 'refs/heads/master' is unchanged
Ref 'refs/remotes/copy/master' was rewritten
WARNING: Ref 'refs/remotes/master/master' is unchanged
$ git merge copy/master
Auto-merging test.txt
Merge made by the 'recursive' strategy.
 test.txt |    5 +++++
 1 file changed, 5 insertions(+)

最后的结果

$ git log --graph --oneline | cat
*   4dadb0a Merge remote-tracking branch 'copy/master'
|\  
| * bb2fc85 G
| * be88bc5 F
| * 0816baf E
* | 1532332 D
* | 90903c0 C
|/  
* 95b0fc8 B
* e9de90c Commit A