git - 更改 git 分支的根目录,将旧提交保留为分支 HEAD?
问题描述
如果我措辞不正确,请原谅我,但我所拥有的是master
,master-variant
后者是我正在研究的通用产品的变体。它包含附加文件和一些更改的文件。
问题是我正在“反向”创建这个,因为我从变体开始,现在需要这个新的通用“根”,因为我将添加从它分支的其他新变体。
所以我从原始变体开始master
并为当前状态创建了一个分支master-variant
,没有任何更改(即它指向与 相同的提交master
)。
然后我修改了 的内容master
以使其“通用”,即删除所有特定于变体的内容并在那里提交。在这种状态下,master
与指向的提交相比,有一个新的提交master-variant
。
但我希望它看起来好像我从泛型开始master
(那里的最后一次提交)然后分支master-variant
出来,并添加了特定于变体的东西,即master
.
我会尽力说明。我所拥有的是这个(m = master
, v = master-variant
):
m0---m1---m2---m3 (changes to create generic variant)
\
v1 (just a new ref to m2)
请注意,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
(即 commit m3
),弹出隐藏状态并将其提交到新master-variant
分支。
但是有没有更直接的方法?
简而言之,我真正想要的是创建一个包含历史提交状态的分支,但将该分支植根于 HEAD(而不是历史提交)。
解决方案
提醒:提交是文件状态的快照。提交本身形成提交图,而分支名称只是标识(指向)特定提交的标签。
你说在你的图表中,v1
实际上是对commit的引用m2
。也就是说,它本身还不是一个单独的提交。所以你真正拥有的是:
C0--C1--C2 <-- v1
\
C3 <-- master
其中v1
和master
是指向由提交本身形成的图形的标签(名称),它们是C0
通过C3
. 您描述自己想要的图表添加了一个新提交C4
,其内容与那些内容匹配C2
但其父级(历史提交就在其后面)是 C3:
C0--C1--C2 C4 <-- v1
\ /
C3 <-- master
鉴于这种情况,您有两个相对简单的选择。一种是进入 Git 的所谓管道命令,并使用一个命令进行新的提交,给它一个特定的保存快照和一组父项。新的提交是你的C4
. 然后,复制C2
到 后C4
,您会将名称移动v1
到指向C4
。两个特定的 Git 命令是:
hash=$(git commit-tree -p master v1^{tree} -F /tmp/message)
其中/tmp/message
包含您要使用的提交日志消息。还要注意,一些 shell 可能会解释^
or{
字符;如果是这样,请引用它们。然后,您可以运行git log $hash
以验证提交是否正确。然后,如果您当前在“on”分支v1
:
git reset $hash
将调整v1
标签。(确保您的索引和工作树是干净的,即没有任何未提交的内容要保存。)如果不是:
git branch -v v1 $hash
将调整v1
标签。
或者,考虑恢复提交C3
将撤销其更改并为您留下匹配的新提交C2
。所以你可以:
git checkout v1
git merge --ff-only master
这将产生:
C0--C1--C2
\
C3 <-- v1 (HEAD), master
然后你只需运行:
git revert HEAD
做一个新的提交,取消和之间的区别C2
,C3
给你一个新的提交C4
:
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
那么该git commit-tree
方法的工作量就会减少(尽管您仍然可以使用,但在这种情况下git revert
,您只需要-n
在恢复C5
,C4
和C3
,或随后git rebase -i
将所有新提交压缩在一起的情况下)。换句话说,git commit-tree
正是实现以下目标的工具:
...我真正想要的是创建一个包含历史提交状态的分支,但将该分支植根于 HEAD (而不是历史提交)。
推荐阅读
- eclipse - Eclipse PyDev 中 streamlit 的“未解析导入”消息
- javascript - 未捕获的类型错误:this.element.getAttribute 不是完整日历鼠标悬停事件的函数
- node.js - 使用动态导入时在 IntelliJ 中保留 Typescript 智能感知
- asp.net-core - 为什么 CSP 在 .net core 和 Angular App 中不起作用?
- python - 如何将字符串和数字列表转换为在python中浮动?
- python - open 属性不适用于 sqlite3dbm
- jquery - 如何在 Django 中从 request.POST 中检索表单数据
- javascript - 将道具从功能组件传递到功能组件时遇到问题
- cas - 如果服务器重新启动,CAS 属性释放同意将被重置
- 3d - 如何计算 3-D 空间中点三角形交点的 y 位置(高度)?