【问题标题】:git rebase after git revertgit revert 之后的 git rebase
【发布时间】:2014-08-31 17:40:36
【问题描述】:

在开发开源项目时,我遇到了以下 git 问题。我做了一些更改,并发送了一个拉取请求。 PR一开始就被接受了。然而,我的更改结果发现有一些微妙的错误,维护者再次恢复了我的提交,要求我在解决问题后发送一个新的拉取请求。然而,在这期间发生了很多其他的提交,所以我需要更新我的拉取请求。不幸的是,我无法让 git 在master 的最新状态之上重新调整或挑选我的旧 PR。

让我用一个例子来澄清一下。比如说,我最初的拉取请求提交了AB 并被接受了。然后,几次提交之后,我的 PR 被恢复(R),然后又发生了一些提交。历史是这样的:

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

现在,我想将其转换为以下形式,以便在master 的最新状态之上优化我的拉取请求:

...--A---B--...--R--...--o master
                          \
                           A---B newPR

但是,rebasecherry-pick 都未能实现这一点。问题似乎是,git 认为AB 已经是master 的一部分,因为它们已经在历史中了。因此,它不会在 master 之上应用这些更改。

如何强制 git 这样做?

【问题讨论】:

  • 你说的我没能做到到底是什么意思?您是否从 Git 收到特定消息?此外,添加您使用的确切的 rebasecherry-pick 命令。
  • @Jubobs Fails 表示AB 的更改不存在。就 git 而言,这不是一个错误。 rebase 命令是git rebase --onto master beforePR B,其中beforePRA 之前的最后一次提交。这直接来自git rebase 手册页。挑选的樱桃是git cherry-pick A..B
  • 有人在这里评论只是为了revert the revert。这实际上工作得很好。不幸的是,我不记得用户名,但如果那个人将其作为答案发布,并且没有更好的魔法出现,那么我很乐意接受。
  • 我快速浏览了man pagecherry-pick 有一个 --keep-redundant-commits 选项。也许这行得通。我会发布它作为答案,但我无法复制您的错误情况;我总是能够挑选一个还原的提交。
  • @musiKk 非常好!我不知道那个选项。我试过了,这是另一个很好的解决我的问题的方法。与还原还原相比,不利的一面是,如果 PR 仅部分还原,那么您的新 PR 将包含空提交。您需要使用rebase -i手动删除的那些...

标签: git rebase cherry-pick


【解决方案1】:

除了cherry-pick 选项,rebase 现在还有一个--force-rebase 选项来生成新的提交,这样它就会忽略之前恢复的合并。

另请参阅:revert-a-faulty-merge How-Togit rebase --no-ff 和完整的 git rebase 文档。

【讨论】:

  • 我有同样的问题,但--no-ff--force-rebase/-f 不起作用。知道为什么吗?
【解决方案2】:

编辑

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

【讨论】:

  • 如果它包含在一台机器上,我会同意这种方法。不幸的是,这将破坏master 的历史。因为master 是一个公共分支,所以是一个很大的禁忌。
猜你喜欢
  • 2011-07-21
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
相关资源
最近更新 更多