更改git分支机构';s根,保留旧提交作为分支头?
如果我的措辞不正确,请原谅,但我拥有的是更改git分支机构';s根,保留旧提交作为分支头?,git,branch,git-rebase,git-rewrite-history,Git,Branch,Git Rebase,Git Rewrite History,如果我的措辞不正确,请原谅,但我拥有的是master和master variant,后者是我正在开发的通用产品的变体。它包含其他文件和一些已更改的文件 问题是,我正在创建这个“反向”,因为我从变体开始,现在需要这个新的通用“根”,因为我将添加从它分支的其他新变体 因此,我从master中的原始变量开始,为当前状态创建了一个分支master variant,没有任何更改(即,它指向与master相同的提交) 然后,我修改了master的内容,使其成为“通用”,即删除所有特定于变体的内容,并将其提交
master
和master variant
,后者是我正在开发的通用产品的变体。它包含其他文件和一些已更改的文件
问题是,我正在创建这个“反向”,因为我从变体开始,现在需要这个新的通用“根”,因为我将添加从它分支的其他新变体
因此,我从master
中的原始变量开始,为当前状态创建了一个分支master variant
,没有任何更改(即,它指向与master
相同的提交)
然后,我修改了master
的内容,使其成为“通用”,即删除所有特定于变体的内容,并将其提交到那里。在此状态下,master
与master variant
指向的提交相比有一个新的提交
但是我想让它看起来像是我从通用的master
(最后一次提交)开始,然后将master variant
从它分支出来,并添加了特定于变量的内容,即master
中上一次提交的状态
我将试着举例说明。我拥有的是这个(m=主变量
,v=主变量
):
请注意,m0
。m2
在master
分支中,但它们的内容是我现在希望在分支中使用的原始变体
我想改变它,让它看起来像这样:
m0---m1---m2---m3 (same as above, the generic variant)
\
v1 (same content as "v1" above, which is also the same content as "m2" in both illustrations)
我怎样才能做到这一点
我的第一个想法是使用git-rebase
,但我看不出这是怎么可能的,因为它所做的是重放提交,而我需要重放提交的相反部分,即m3
提交的相反部分
我想我可以隐藏m2
/v1
状态,删除master variant
分支,切换到master
(即提交m3
),弹出隐藏状态并将其提交到新的master variant
分支
但有没有更直接的方法
简言之,我想我真正想要的是创建一个包含历史提交状态的分支,但将该分支在头部扎根(而不是在历史提交处)。提醒:提交是文件状态的快照。提交本身构成提交图,而分支名称只是标识(指向)特定提交的标签
您说过在您的图表中,v1
实际上是提交m2
的引用。也就是说,它本身并不是一个单独的提交。所以你真正拥有的是:
C0--C1--C2 <-- v1
\
C3 <-- master
考虑到这种情况,您有两个相对简单的选择。一种是进入Git所谓的管道命令,使用一个命令进行新的提交,给它一个特定的保存快照和一组父对象。新提交是您的C4
。然后,将C2
复制到C4
后,您将移动名称v1
指向C4
。用于此目的的两个特定Git命令是:
hash=$(git commit-tree -p master v1^{tree} -F /tmp/message)
其中/tmp/message
包含要使用的提交日志消息。还要注意,一些shell可能会解释^
或{
字符;如果是,请引用它们。然后,您可以运行git log$hash
,以验证提交看起来是否正确。然后,如果您当前处于分支v1
上,请执行以下操作:
git reset $hash
将调整v1
标签。(确保索引和工作树是干净的,即没有未提交的内容要保存。)如果没有:
将调整v1
标签
可选地,考虑将提交<代码> C3恢复其更改并留给您一个新的提交,它与<代码> C2 < /代码>匹配。因此您可以:
git checkout v1
git merge --ff-only master
这将产生:
C0--C1--C2
\
C3 <-- v1 (HEAD), master
要进行新的提交以消除C2
和C3
之间的差异,请执行新的提交C4
:
C0--C1--C2 C4 <-- v1 (HEAD)
\ /
C3 <-- master
C0--C1--C2 C4非常详细和解释。谢谢!阅读git提交树
并首先尝试,但出现错误“致命:007a[snip]d8f不是有效的“树”对象”。不确定为什么不起作用。(想法?)但我随后尝试了还原方法,得到了我想要的结果。问题解决了。竖起大拇指!哦,我在上面犯了一个错误(将修复它)-您需要指定一个^{tree}
后缀,因为git commit tree
不会解析对其树的提交。谢谢。尝试查找关于^{tree}的文档
但是失败了。如果您能给我一个提示,我将不胜感激。一般参考语法?在这里可以找到关于^{tree}
的文档:但我想我必须多读一点,才能完全理解上下文中的相关性。当然,欢迎您提供任何其他链接或解释。请参阅^{…}
后缀语法指示内部修订解析器尝试将对象(以后缀之前的任何名称命名)转换为给定类型的对象。有一种没有类型的速记,表示“取消引用标记”。
git checkout v1
git merge --ff-only master
C0--C1--C2
\
C3 <-- v1 (HEAD), master
git revert HEAD
C0--C1--C2 C4 <-- v1 (HEAD)
\ /
C3 <-- master
C0--C1--C2 <- v1
\
C3--C4--C5 <-- master
C0--C1--C2 C6 <- v1
\ /
C3--C4--C5 <-- master