将任何Git提交从一个分支移动到另一个分支

时间:2012-01-24 18:29:02

标签: git

我有以下Git提交树:

R - A - B - C - D (master)

我想:

R - A - B - D' (master)
        \ - C  (new-branch)

我怎么能这样做(假设它甚至可能)?

我开始使用git cherry-pick,但我没有设法从主分支中删除提交。

感谢。

4 个答案:

答案 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