我需要将多个来自分支或远程仓库的提交合并到另一个分支中的单个提交中。
input branch#1: o--o- - -o (C1)
\
input branch#2: o--o- - -o | (C2)
: \|
input branch#N: o--o- - -o | (Cn)
\|
output branch: o--o- - -o (Cm)
我需要以一种特殊的方式来做到这一点,其中每个输入分支合并提交的源树是输出分支合并提交的源树中的前缀或子目录:
<C1> <C2> ... <Cn>
| | |
+- c1.txt +- c2.txt +- cn.txt
<Cm>
|
+- C1/c1.txt
|
+- C2/c2.txt
|
: :
|
+- Cn/cn.txt
此外,我需要更改合并提交的一些参数,例如author date
,author email
等,并从所有输入分支的提交消息中生成提交消息,使合并提交的父级保持不变(包括合并中的父级提交哈希列表)犯罪)。
在互联网上挖掘我已经找到了使用最少命令集的最通用的解决方案:
git merge --allow-unrelated-histories --no-edit --no-commit -s ours <input-branches-and-commits>
git read-tree --prefix=C1/ <C1-branch>
git read-tree --prefix=C2/ <C2-branch>
:
git read-tree --prefix=Cn/ <Cn-branch>
cat ... | git commit --no-edit --allow-empty --author="..." --date="..." -F -
但是当输出分支是孤立分支时,它的工作方式会有所不同。在这种情况下,输入分支的内容会额外合并到输出分支提交的源树的根中:
<Cm>
|
+- C1/c1.txt
|
+- c1.txt
基本上,当输入分支是唯一的输入分支时会发生这种情况(当输出分支是孤立分支时,我没有测试多个输入分支的情况,因为我还没有这种情况,但我不排除这种情况)。
我找到了发生这种情况的原因。因为头还不存在并且不能存在,包括输出分支,所以合并命令在调用时创建它,同时使合并不完整,输出分支指向输入分支,这实际上使输出分支成为父分支对自己。这会将输入分支的源代码树的内容带入输出分支提交的源代码树的根目录,而无需用户通知。
我知道至少有一种方法可以避免这种行为,例如,在合并之前在输出分支中创建一个空提交,这使得孤立分支不是孤立的,并将头部与对输出分支的引用一起初始化。
但我不希望这样做,因为我必须稍后以某种方式删除该提交,这实际上是 git 的解决方法代码。
是否存在一种众所周知的方法来处理 git 的胆量以使所有事情都按预期工作并合并在一起?