[英]git: how to move a branch's root two commits back
比方说我有:
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
是我正在寻找的功能,但我想在我搞砸我的存储库之前确定。
(我搜索并发现了许多非常相似的问题和例子,但没有一个与我描述的场景完全相同 ,所以我要求确定(回购是一件珍贵的事情,毕竟毁了))。
Edmundo的答案是正确的(并且已经投票),但值得指出一些额外的项目。
首先,你的问题谈到“移动分支的根” - 但这是Git; 分支机构没有根,没有你在想反正方式。 我们来看看你的图形图:
A - B - C - D - E - F master
\
\- G - H new feature branch
我认为你和我一样,当我第一次开始使用Git时,想要将ABCDEF
提交master
分支,并将GH
作为功能分支提交。 但这不是Git的工作方式。 让我们重新绘制它,而不更改任何提交链接:
E--F <-- master
/
A--B--C--D
\
G--H <-- feature
这应该更清楚地表明,就Git而言,承诺ABCD
都在两个分支上。 只有一个根。 这是提交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
基本上复制了一个提交。 新副本“与原始副本做同样的事情”,但有一些不同的东西 ,即使它像“我的父母是......”一样简单。 (通常它也有不同的附着树对象,以及,它只是使浓度变化 ,相比其新的母公司时,相同的时候原来是相对于原来的母公司原来做的改变)。 这意味着你实际上无法获得你想要的东西,只需要你需要的东西 :
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
-does是以花哨的自动化方式完成这些副本,最后一步是移动分支名称,放弃原始提交。 所以git rebase -i
有时候更容易实现。
如果你运行git rebase -i
你会看到所有那些pick
命令,而那些字面上运行git cherry-pick
:它真的是在做一系列的挑选。 如果您自己进行这些操作,可能会更清楚地发生了什么,并且您可以更好地控制何时移动分支标签。
1对于合并提交,这是父s ,复数。 所有的父母都参与哈希。
修复大师:
git checkout A
git cherry-pick master~3..master # apply the changes we actually want to keep on master
git branch -f master # reposition master on new position
git checkout master
要从功能分支中删除提交D:
git checkout feature-branch~3 # or git checkout C
git cherry-pick feature-branch~2..feature-branch # apply the last 2 revisions
git branch -f feature-branch
git checkout feature-branch
你可以用git rebase
做到这一点。
首先,让我们修改一些来自master
提交:
$ git checkout master
$ git rebase --onto A C
这将把所有提交范围从C转换为master
(但不包括C本身)到提交A.
现在rebase feature
但抛出提交D:
$ git checkout feature
$ git rebase --onto C D
到前面的命令类似,这将在从d的范围内移动的提交到feature
(不包括d本身)到C.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.