在 git revert 后使用 git rebase

3
在参与一个开源项目时,我在使用 git 时遇到了以下问题。我进行了一些更改,并发送了一个 pull-request。起初,这个 PR 被接受了。然而,我的更改后来被发现存在一些微妙的错误,因此维护者撤销了我的提交,并要求我修复问题后再次发送 pull-request。然而,在此期间已经有很多其他的提交了,因此我需要更新我的 pull-request。不幸的是,我无法让 git 在最新的 master 状态上重新应用我的旧 PR 或 cherry-pick。

让我通过一个例子来澄清一下。假设我的原始 pull-request 包含提交 AB 并被接受了。然后,几个提交之后我的 PR 被撤销了 (R),然后又发生了几个提交。历史记录看起来像这样:

...--A---B--...--R--...--o master

现在,我想将其转换成以下形式,以便在最新的master状态上改进我的拉取请求:
...--A---B--...--R--...--o master
                          \
                           A---B newPR

然而,我使用rebasecherry-pick都没有成功。问题似乎是git认为AB已经是master的一部分,因为它们已经在历史记录中了。所以,它不会将这些更改应用于master之上。如何强制git执行此操作?

1
你所说的“我未能实现这个”的具体意思是什么?你从Git得到了特定的消息吗?另外,请添加你使用的确切rebasecherry-pick命令。 - jub0bs
@Jubobs 失败 意味着 AB 的更改不在那里。就 Git 而言,这不是错误。rebase 命令是 git rebase --onto master beforePR B,其中 beforePRA 之前的最后一个提交。这是从 git rebase 手册中直接摘录的。cherry-pick 是 git cherry-pick A..B - Lemming
3
这里有人建议只需“撤销还原”。这个方法非常有效。不幸的是,我忘记了这个用户的用户名,但如果那个人把它发布为答案,并且没有更好的方法出现,那么我将很乐意接受它。 - Lemming
3
我快速查看了man pagecherry-pick命令有一个--keep-redundant-commits选项,也许这个选项可以解决你的问题。我本想回答并发布此答案,但是我无法复制你的错误状况;我总是能够cherry-pick一个被还原的提交。 - musiKk
@musiKk 很好!我之前不知道这个选项。我试了一下,它是解决我的问题的另一个好方法。与还原撤销相比的缺点是,如果 PR 只被部分撤销,那么你的新 PR 将包含空提交。你需要使用 rebase -i 手动删除它们... - Lemming
2个回答

3

我有同样的问题,但是 --no-ff--force-rebase/-f 都无法解决。有任何想法为什么吗? - RafazZ

0

已编辑

git checkout master
git checkout -b redo
git cherry-pick Aref
git cherry-pick Bref
... do fixes and commits
git merge master

之前

* e553928d35646512f640b0f0ca208f6729884993 D
* 5157867afdbdcf4300f7b722e3816e294e0f2ae4 C
* caa01fd5378f87b67811212aa4325963fab72905 Revert "A"
* 8603f6b1231dbefa4911699cb59fa81f1a20e432 Revert "B"
* d4c38c2c63ab0b4be00480bf9c9542ffc66dcb5f B
* f2f6e0a0b7a804a4a8075839d7b73b37b747a7b3 A
* 59597e64b49b234b45a94a86d950f0811a19cdfe root commit

之后

* e6a314b66d8be8a85abd6becd53e0d2c7a6332a5 E
* d7d91af4225d5ba7d783303e73bcac1b5ba02a91 B
* 381b95bea7f87662f72a1da67bd70cdfc497be47 A
* e553928d35646512f640b0f0ca208f6729884993 D
* 5157867afdbdcf4300f7b722e3816e294e0f2ae4 C
* caa01fd5378f87b67811212aa4325963fab72905 Revert "A"
* 8603f6b1231dbefa4911699cb59fa81f1a20e432 Revert "B"
* d4c38c2c63ab0b4be00480bf9c9542ffc66dcb5f B
* f2f6e0a0b7a804a4a8075839d7b73b37b747a7b3 A
* 59597e64b49b234b45a94a86d950f0811a19cdfe root commit

在本地运行正常

$ git checkout master
Switched to branch 'master'
$ ls
A B C D E

1
如果这个方法只在一台机器上运行,我会同意这种做法。但不幸的是,这将破坏“主分支”的历史记录。而且,“主分支”是公共分支,这是不可取的。 - Lemming

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