在不同的分支上重新播放最近的N个git提交

58

我在分支“testing”上意外地提交了10个更改,但本来打算将它们提交到“master”分支。由于“testing”分支上的其他更改都是垃圾,所以我不想将其与“master”合并。相反,我只想在“master”上重新播放最后的10个提交。

3个回答

112

使用变基应该可以解决问题。

git rebase -p --onto master testing~10 testing
这将把测试分支上的最近10次提交复制到主分支并使其成为新的测试分支(旧的测试分支将成为孤儿分支)。然后,您可以将主分支作为快进合并到测试分支。
git checkout master
git merge testing

12
值得注意的是,这将使测试分支与主分支处于相同的位置,留下了“垃圾”提交无人问津。这可能是好事,也可能不是。另一个可能性是git checkout master; git reset --hard testing; git rebase --onto HEAD@{1} HEAD~10。 - CB Bailey
@CharlesBailey 你打算攻击哪个 git flog? - Fredrick
可以这样说,rebase 的优点是更改只存在于一个地方,但如果更改已经推送到另一个仓库(例如 origin),cherry-pick 的效果更好。 - LexH
-p(保留)标志现已被弃用(当您尝试使用它时,会出现“fatal: --preserve-merges已被--rebase-merges替代”的错误提示,我的git版本为2.38.0)。 - Sandra

26
  1. git checkout 主干
  2. git whatchanged 测试
  3. git cherry-pick _________


6
提醒一下,挑选特定提交只能一次处理一个提交,所以你需要挑选 testing9、testing8 等多个提交。这就是为什么我更喜欢 Talljoe 建议的变基方法......当然结果是相同的。实际上,如果你用交互式方式进行变基,Git 会在内部使用挑选特定提交的方式。 - Pat Notz
14
git cherry-pick 目前可以一次选择多个提交(例如,git cherry-pick testing~10..testing)。 - Max Nanasy
你永远不应该使用 cherry-pick。阅读这篇文章以获取更多信息。 - Tim
5
“从语义上来说,‘never’这个词有点过于强烈了。” - prasanthv
3
你说得对,我的意思是:不要把“挑拣”作为你的工作流基础。Git 的“挑拣”在其他情况下非常有用,但不应该用于将提交从一个分支移动到另一个分支,有更好的工具可以做到这一点 :) - Tim
显示剩余3条评论

1
正如评论中所说,受rebase启发的答案是将“垃圾”提交孤立。
只需使用简单的工具:
git checkout master
git merge testing
git checkout testing
git reset --hard HEAD~10   # Go back 10 commits (*1)
git checkout master

(*1) 由于合并操作,您将只会失去来自 testing 分支的提交记录,因为这些提交记录已经在 master 中了。


1
这种方法不会将垃圾提交与 OP 想要合并的 10 个提交一起合并到“主分支”中吗? - mpavey
1
现在我明白了OP关于这些垃圾提交的问题。你是对的,这些已经合并到主分支了,忘记我的建议吧。那么问题来了,OP想要删除这些垃圾提交但保留结果代码,还是完全放弃这项工作?我认为后者需要挑选而前者需要变基。 - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接