【问题标题】:Revert a range of commits in git恢复 git 中的一系列提交
【发布时间】:2011-06-26 20:52:17
【问题描述】:

如何恢复 git 中的一系列提交?通过查看gitrevisions 文档,我看不到如何指定我需要的范围。例如:

A -> B -> C -> D -> E -> HEAD

我想做相当于:

git revert B-D

结果会在哪里:

A -> B -> C -> D -> E -> F -> HEAD

其中 F 包含 B-D 的倒数。

【问题讨论】:

  • 在 gitrevisions(7) 页面的末尾,有一个标题为“指定范围”的部分。您想要的与那里描述的有何不同?
  • gitrevisions 页面建议 'git revert A..​​D' 会做我想做的事。但是,当我尝试时,我收到错误“致命:找不到'A..D'”

标签: git revert range


【解决方案1】:

你使用的是什么版本的 Git?

仅在 Git1.7.2+ 中支持恢复多个提交:有关详细信息,请参阅“Rollback to an old commit using revert multiple times.”。
当前的git revert man page 仅适用于当前 Git 版本(1.7.4+)。


正如 OP Alex Spurling 在 cmets 中报告的那样:

升级到 1.7.4 可以正常工作。
为了回答我自己的问题,这是我正在寻找的语法:

git revert B^..D 

B^ 表示“B 的第一个父提交”:允许在还原中包含 B
请参阅包含 <rev>^, e.g. HEAD^ 语法的“git rev-parse SPECIFYING REVISIONS section”:在“What does the caret (^) character mean?”查看更多信息)

请注意,每个还原的提交都是单独提交的。

Henrik Nthe comments澄清:

git revert OLDER_COMMIT^..NEWER_COMMIT

如下图,无需立即提交即可还原:

git revert -n OLDER_COMMIT^..NEWER_COMMIT
git commit -m "revert OLDER_COMMIT to NEWER_COMMIT"

【讨论】:

  • 谢谢,这就是答案。升级到 1.7.4 可以正常工作。为了回答我自己的问题,这是我正在寻找的语法: git revert B^..D
  • 天才。谢谢。我没有想到我需要以相反的顺序恢复提​​交才能应用补丁,呵呵。此命令显示方式。
  • 我经常参考这个答案,而且我总是需要一段时间才能弄清楚顺序。所以帮助我未来的自己:git revert OLDER_COMMIT^..NEWER_COMMIT
  • ^ 是什么意思?
  • @DustinGetz 第一父级:参见git-scm.com/docs/gitrevisions:“修订参数的后缀^ 表示该提交对象的第一父级”。
【解决方案2】:

如果你想在一次提交中将提交范围 B 恢复为 D(至少在 git 版本 2 中),你可以这样做

 git revert -n B^..D

这会将提交完成的更改从 B 的父提交(排除)还原到 D 提交(包含),但不会创建任何包含还原更改的提交。 revert 只修改工作树和索引。

之后别忘了提交更改

 git commit -m "revert commit range B to D"

您还可以使用相同的方法在单个提交中还原多个不相关的提交。例如恢复 B 和 D 但不恢复 C

 git revert -n B D
 git commit -m "Revert commits B and D"

参考:https://www.kernel.org/pub/software/scm/git/docs/git-revert.html

感谢Honza Haeringcorrection

【讨论】:

  • git revert -n B..D 不会恢复提交 B,只有 C 和 D。git revert -n B^..D 也会恢复 B。
  • 根据 git 文档。参考帖子
  • 如果您在参考文献中引用此示例(我认为这有点令人困惑):git revert -n master~5..master~2,它表示包括第五次最新提交。但master~5 实际上是第 6 次最新提交。有关 .. 符号的详细信息,请参阅 git 文档中的 revision selection :-)
  • 如果您打算重新应用这些提交,这通常是个坏主意
【解决方案3】:

git revert OLDER_COMMIT^..NEWER_COMMIT 对我不起作用。

我使用了git revert -n OLDER_COMMIT^..NEWER_COMMIT,一切都很好。我正在使用 git 版本1.7.9.6

【讨论】:

  • 我也遇到了同样的问题并使用 -n 修复它,但您应该将 ^ 保留为 OLDER_COMMIT (git revert -n OLDER_COMMIT^..NEWER_COMMIT)。
  • @FeelGood 你为什么要离开^?
  • 我有历史 A -> B -> C,目标是还原 B 和 C。当我运行“git revert -n B..C”时,只有 C 被还原。当我使用 'git revert -n B^..C' 时,git 恢复了两个提交。也许我做错了什么。
  • 酷,必须对其进行测试,但我认为在我的情况下效果很好(除非我正在恢复 1 个提交范围,哈哈)我会修改答案以包含 ^。谢谢
  • -n--no-commit 选项将在单个提交中还原整个范围内的所有更改,而不是为范围内的每个提交创建一个还原提交。最终结果是一样的,因为相同的更改将被还原。只是取决于你希望你的 git 历史是什么样子。
【解决方案4】:

使用git rebase -i 将相关提交压缩为一个。然后,您只需还原一个提交。

【讨论】:

  • 如果使用 git rebase,您可以简单地删除提交。我认为有理由不重新设置基准,例如希望保持提交 F 的 SHA1 相同。
  • 或者,将还原提交压缩为一个。
  • 我猜你可以将它们压缩到一个单独的分支上,还原该提交,然后将还原的提交挑选到原始分支上。
猜你喜欢
  • 2016-06-23
  • 1970-01-01
  • 2021-04-13
  • 2011-07-12
  • 1970-01-01
  • 2018-10-17
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多