- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
假设我有:
A - B - C - D - E - F master
\
\- G - H new feature branch
现在我意识到提交 B 和 C 实际上属于新功能,所以我想把它们移动到“新功能分支”。换句话说,我希望“新功能分支”从 A 开始,并包括提交 B 和 C:
A - D - E - F master
\
\- B - C - G - H new feature branch
我该怎么做?从我读过的内容来看,rebase
似乎是我正在寻找的功能,但我想在弄乱我的存储库之前确定一下。
(我搜索并发现了很多非常相似的问题和示例,但没有一个完全像我描述的场景,所以我要求确定(a毕竟,repo 是一件很珍贵的东西)。
最佳答案
Edmundo's answer是正确的(并且被赞成),但值得指出一些额外的项目。
首先,您的问题是关于“移动分支的根”——但这是 Git; Twig 没有根,反正不是你想的那样。让我们看看您绘制的图表:
A - B - C - D - E - F master
\
\- G - H new feature branch
我想当我刚开始使用 Git 时,你和我一样,会认为提交 A-B-C-D-E-F
是在 master
分支上,并且提交 G-H
作为功能分支。但这不是 Git 的工作方式。让我们重新绘制它,而不更改任何提交链接:
E--F <-- master
/
A--B--C--D
\
G--H <-- feature
这应该更清楚地表明,就 Git 而言,提交 A-B-C-D
在两个 分支上。只有一个根。那是提交 A
:它是根,因为它没有父提交,从提交到父的链中没有向后链接。
其次,无论您如何处理,最终都必须复制一些提交。原因是每个提交的父 ID 都是该提交身份的一部分。任何提交的“真实名称”是其哈希 ID,哈希 ID 是通过读取提交的完整内容构建的:源代码树、提交消息、作者姓名和日期等,但始终包括父 ID。 1 您希望最终图表类似于:
D--E--F <-- master
/
A
\
B--C--G--H <-- feature
但现有的 D
链接(或指向)现有的 C
,而不是 A
,以及现有的 G
指向现有的 D
。
这就是 cherry-pick 起作用的原因:git cherry-pick
本质上是复制 一个提交。新副本与原始副本“做同样的事情”,但有某些不同之处,即使它像“我的 parent 是......”一样简单。 (通常它也有一个不同的附加树对象,只是它所做的改变,当与它的新父级相比时,与原始的改变相同当将原件与原件的父级进行比较时生成)。这意味着 you can't actually get what you want, just what you need :
D'-E'-F' <-- master
/
A
\
B--C--G'-H' <-- feature
其中的小勾号表示结果是原件的副本。
原件会怎样?答案是:它们仍然存在于存储库中,以备不时之需。完整的画面更像这样:
D'-E'-F' <-- master
/
/ E--F [abandoned]
/ /
A--B--C--D
\ \
\ G--H [abandoned]
\
G'-H' <-- feature
虽然 git cherry-pick
可以工作,但是 git rebase
——尤其是 git rebase -i
——所做的只是花哨地做这些副本自动化方式,最后一步移动分支名称,放弃原始提交。所以 git rebase -i
有时是一种更简单的方法。
如果你运行 git rebase -i
你会看到所有那些 pick
命令,而且那些字面上运行 git cherry-pick
:它确实是做一系列的 cherry-pick 。如果您自己执行这些操作,可能会更清楚发生了什么,并且您可以更好地控制何时移动分支标签。
1对于 merge 提交,这是父s,复数形式。所有家长都参与哈希。
关于git:如何将分支的根两个提交移回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43531189/
我是一名优秀的程序员,十分优秀!