我无法将开发分支的子树合并回集成分支。
我有两个分支,一个用于开发,一个用于集成。在开发分支中已经进行了广泛的开发,我想将其中的一部分合并回来。我想要合并的特定部分都包含在开发分支的一个子树中。
我的目录结构如下:
[Branch A] [Branch B]
| |
+--Dir1 +--Dir1
+--Dir2 +--Dir2
| | |
+--DirA | +--DirA
| | |
+--File1 | +--File1
+--File2 | +--File2
| +--File3
| +--File4
+--Dir3
我想将Branch B / Dir2 / DirA合并到Branch A / Dir2 / DirA中。我希望合并File1和File2,并且应该在分支A中创建File3和File4。我不想选择Dir3,或者Dir1中的任何更改。
我已经尝试了kernel.org为merging subtrees概述的步骤,但是当我使用git read-tree时它们会失败:
error: Entry 'Dir1/DirA/File1' overlaps with 'Dir1/DirA/File1'. Cannot bind.
我已经尝试使用github上托管的subtree script,但我没有太多运气。当我这样做时:
git checkout Branch_A
git subtree merge -P Dir2/DirA Branch_B
我看到证据表明Dir3已经合并,合并失败并伴随着冲突。
我可以挑选合并的文件,但这对于应该是一个普通而直截了当的问题似乎有点不必要。
答案 0 :(得分:1)
你想要的可能只是:
git merge Branch_B -s ours [OPTIONAL]
git checkout Branch_B Dir2/DirA
此配方将子树从Branch_B复制到Branch_A,(OPTIONALLY)也在git的项目历史中创建合并提交:
如果您不在,请切换到Branch_A。
git checkout Branch_A
(可选)建立合并提交,而不更改工作区中的任何文件(merge策略“我们的”)。这个“空”提交只是将另一个分支添加为第二个父,创建历史链接。如果这对你不重要,你可以跳过这一步;后续步骤不需要它。
git merge Branch_B -s ours
注意:只能在干净的工作区中执行此操作;如果您修改或暂存了任何文件,则此命令可能会失败。
将子树Dir2 / DirA的内容从Branch_B复制到您的工作区,而不更改您的活动分支。
git checkout Branch_B Dir2/DirA
将Branch_B中的文件提交到Branch_A。如果省略--amend
,则会为此步骤创建新的提交;使用它会使新文件成为早期合并提交的一部分。
git commit --amend
步骤3中checkout的形式可能看起来不太熟悉,但官方文档指出,当此表单未时,习惯性的分支切换行为实际上只是一种便利:< / p>
如果没有给出路径,git checkout也会更新HEAD以将指定的分支设置为当前分支。
因此,如果您提供显式路径,则不会切换分支,只需从该路径复制文件。
答案 1 :(得分:1)
你遇到的问题是git并不是为了做这样的事情而设计的。请考虑以下历史记录,该问题可能会导致问题中的两个分支A
和B
:
C - D - E - F - G - H
\
H - I
分支A
指向提交I
,分支B
指向提交H
。现在,您希望将B
中的一些更改接收到A
。
例如,提交D
和F
已修改Dir2
,E
,G
和H
对Dir1
做了一些事情, Dir3
。实际上,您只希望将提交D
和F
添加到集成分支A
。
这意味着分支B
没有足够仔细地创建,并且您实际上想要将其重做为(至少)两个干净的主题分支。类似的东西:
git checkout -b topic_I_want_to_merge_touching_Dir2 C
git cherry-pick D
git cherry-pick F
git checkout -b topic_I_dont_want_to_merge_now C
git cherry-pick E
git cherry-pick G
git cherry-pick H
git checkout B
git merge topic_I_want_to_merge_touching_Dir2
如果有提交同时触及Dir1
和Dir2
,则这些提交“不好”,因为它们不会解决单个主题,而是同时执行多项操作。在这种情况下,您可能不仅要重新调整提交,还要使用git-rebase -i
将提交更改为好的提交。
当然你可以合并分支A
并修复生成的树。但这样就很难继续处理A
中的“非合并”更改,因为当您合并A
的后代时,您将不得不再次修复生成的树,因为E
,G
和H
的更改不会包含在git为您准备的树中,因为这些提交已经合并。
答案 2 :(得分:0)
合并子树实际上是指将外部项目的一部分合并到项目中。我将参考此博客文章来完成您想要做的事情:http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
答案 3 :(得分:-2)
我只是让dirA成为一个子模块并为它引入第三个回购。