我有以下Git提交树:
R - A - B - C - D (master)
我想:
R - A - B - D' (master)
\ - C (new-branch)
我怎么能这样做(假设它甚至可能)?
我开始使用git cherry-pick
,但我没有设法从主分支中删除提交。
感谢。
答案 0 :(得分:3)
你无法得到你想要的东西,因为提交会有所不同,但如果你这样做,文件的内容就会如你所愿:
$ git checkout master $ git reset --hard sha1-of-B # set master back to B $ git cherry-pick sha1-of-D # set master to R-A-B-D' $ git checkout -b new-branch sha1-of-B # set new-branch to B $ git cherry-pick sha1-of-C # set new-branch to R-A-B-C'
请注意,您并不需要选择设置新分支,您可以轻松地做到:
$ git reset sha1-of-C
当您检查新分支时。这实际上会给你R-A-B-C而不是R-A-B-C'。请注意,C和C'之间的唯一区别是提交时间。
重置后,您可能很难找到各种提交的sha1哈希值(可以从reflog中获取),因此您可能希望在开始之前将标记放在所有内容上,或者将历史记录存储在某处
答案 1 :(得分:3)
通过直接在C创建new-branch来避免不必要的挑选,然后简单地使用rebase来删除提交C:
主人:
git branch new-branch sha1-of-C
git rebase --onto sha1-of-C^ sha1-of-C master
第二个命令通过重新设置master
(git-rebase手册页中的“branch”)从sha1-of-C
(“upstream”)开始提交到{{1}之前的提交,从master中删除C }。
如果第二个命令太混乱,你可以交互式地进行rebase:
sha1-of-C
在交互式rebase上,只需删除提交C,保存并退出。
在变基期间,如果git抱怨合并冲突,请解决它们,git rebase -i sha1-of-C^
和git add
。无论您选择哪种方法,都必须解决这些冲突。
答案 2 :(得分:1)
主人:
git branch new-branch
git reset --hard B
git cherry-pick D
git checkout new-branch
git reset --hard C
答案 3 :(得分:0)
不涉及 B 或 sha1-of-C 等变量的食谱:
git checkout master
如果尚未签出。
git branch tempD # create temporary branch, pointing to D
git branch new-branch HEAD^ # create new-branch, pointing to C
git reset --hard HEAD^^ # reset master to B
git cherry-pick tempD # apply D's changeset onto B
git branch -D tempD # remove temporary branch