将一个分支合并到另一个分支的文件夹中

时间:2019-07-03 15:28:45

标签: git

我有一个分支A,其中的文件夹名为foo。另一个名为B的分支仅包含文件夹foo的内容。是否可以将分支B合并到分支A的文件夹foo中?

分支A包含例如

foo/
    hello_world.c
goo/
    AliceAndTom.c

分支B仅包含文件夹foo /

的内容
./
    hello_world.c
    hello_world.h

合并分支B后在分支A中获得的结果:

foo/
    hello_world.c
    hello_world.h
goo/
    AliceAndTom.c

修改: 分支B是使用git命令git filter-branch --subdirectory-filter dir/to/filter -- subdir_branch

创建的

1 个答案:

答案 0 :(得分:1)

您不能直接将其合并。

在评论中,关于git的重命名检测是否会帮助这里有些困惑。根据您所说的创建分支(使用filter-branch)的说法,很可能不会创建分支。这是因为新分支可能与旧分支没有共同的祖先。[1]

因此,首先您必须解决让git从分支识别相应文件的问题;然后必须解决以下问题:对于该文件的两个当前状态,它仍然不知道最新的共同祖先,因此合并将无法顺利进行。 (两个分支上都存在的每个文件很可能在整个文件上发生冲突,而不是真正合并任何文件。)

这是由于“不同分支上的内容不同”而引起的问题之一;这不是git的工作原理,它会使分支之间的更改集成非常繁琐。

这将是多么繁琐的操作取决于自filter-branch运行以来每个分支上文件的更改量。我能想到的最通用的程序是:

(1)编写一个脚本,将文件移回其子目录

(2)在较新的分支上运行filter-branch(使用上面的脚本作为树过滤器),创建另一个结构更接近原始分支的分支

(3)标识新分支中与原始分支中的提交相对应的最后一个提交

(4)使用git replace替换上面确定的提交,以代替原始分支中的相应提交。

(5)现在,您应该能够将新分支合并到原始分支。然后,您可以撤消git replace并可能处置新分支。

要了解有关每个步骤的详细信息;这不是一个简单的过程,因此,如果要继续使用它,请参考相关命令的文档。


[1]-更具体地说,要应用重命名检测,git必须查看一个修补程序,该修补程序既删除文件,又创建具有足够相似内容的另一个文件(位于不同路径)。

如果您是从master分支出来的,然后在分支上进行了提交,以移动文件,那么现在您将看到类似

x -- x -- O -- A <--(master)
           \
            x -- x -- B <--(bramch)

branch合并到master时,git将查看OB之间的补丁,该补丁符合重命名检测的条件(只要移动的文件没有太大变化)。

但是filter-branch可能创建了一个完全独立的历史记录

x -- x -- x -- A <--(master)

x -- x -- B <--(branch)

默认情况下,合并将失败(没有共同的历史记录),并且如果您使合并没有失败(通过说允许不相关的历史记录),则合并的行为就好像合并基数为空的TREE(即没有文件)。从该补丁到A的补丁创建了foo/file,从那个补丁到B的补丁创建了file,但是这两个补丁都没有删除文件并创建一个路径。 ,因此不会发生重命名检测。合并将创建文件的第二个副本。