Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更改git分支机构';s根,保留旧提交作为分支头?_Git_Branch_Git Rebase_Git Rewrite History - Fatal编程技术网

更改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