我有一个分支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
答案 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将查看O
和B
之间的补丁,该补丁符合重命名检测的条件(只要移动的文件没有太大变化)。
但是filter-branch
可能创建了一个完全独立的历史记录
x -- x -- x -- A <--(master)
x -- x -- B <--(branch)
默认情况下,合并将失败(没有共同的历史记录),并且如果您使合并没有失败(通过说允许不相关的历史记录),则合并的行为就好像合并基数为空的TREE
(即没有文件)。从该补丁到A
的补丁创建了foo/file
,从那个补丁到B
的补丁创建了file
,但是这两个补丁都没有删除文件并创建一个路径。 ,因此不会发生重命名检测。合并将创建文件的第二个副本。