Git:还原连续但不是最新的多个提交

Git:还原连续但不是最新的多个提交,git,git-revert,Git,Git Revert,我阅读,这正是我想要的结果。但是,我确实希望在一次提交中还原所有内容,因为1有许多提交需要还原2我可能需要稍后还原 我比链接中的例子更幸运,因为在回复的中间没有保留。这就是我的历史: A–C1–C2–C3–C4–O1–O2–O3 其中四个C提交是我想要还原的,而O提交是由其他作者稍后进行的 如何在一个commit R中恢复四个C,稍后可以恢复为使所有C再次生效?与许多git命令一样,请特别参阅选项的说明。这意味着,除其他外,您可以简单地传递一系列提交,如中所述。记住C1..C4不包括C1本身,

我阅读,这正是我想要的结果。但是,我确实希望在一次提交中还原所有内容,因为1有许多提交需要还原2我可能需要稍后还原

我比链接中的例子更幸运,因为在回复的中间没有保留。这就是我的历史:

A–C1–C2–C3–C4–O1–O2–O3
其中四个C提交是我想要还原的,而O提交是由其他作者稍后进行的


如何在一个commit R中恢复四个C,稍后可以恢复为使所有C再次生效?

与许多git命令一样,请特别参阅选项的说明。这意味着,除其他外,您可以简单地传递一系列提交,如中所述。记住C1..C4不包括C1本身,所以如果使用此表单,请编写C1^..C4或A0..C4

这将负责指定要还原的提交,但仍然会留下一个进行四次新提交的还原:

$ git revert 22b38d1^..676699a
不做你想做的。2你想做的也列在这些选项中,只是-n或-no提交,同样的事情:

$ git revert -n 22b38d1^..676699a
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
You are currently reverting commit 22b38d1.
  (all conflicts fixed: run "git revert --continue")
  (use "git revert --abort" to cancel the revert operation)
[remainder snipped]
所有四次提交现在都已恢复,但尚未执行任何提交,因此现在我必须手动提交结果。如果我运行git revert-continue,git将为我进行一次提交,但只会提到第一次恢复22b38d1,在这种情况下,恢复是反向进行的,如果需要恢复上一次提交,则先执行676699a,依此类推

$ git commit
这将使用reverts the first commit message(还原第一条提交消息)打开编辑器,我现在可以一次性修复它,说Reverte 22b38d1^..676699a。构建一个好的回归消息可能很困难;git对于自动提交的默认值已经足够了,但是在本例中,使用-n的默认值就不够了

Git是Git,当然,您可以使用相同的技术,而不使用-n和Git-rebase,我在您的链接帖子中提到过:将四个恢复压缩为一个单一的恢复,但是使用压缩操作来组合提交文本。在这里,您可以运行:

$ git revert --no-edit 22b38d1^..676699a
[messages omitted]
$ git rebase -i HEAD~4
[editor runs: change last three to "squash", write, exit editor]
[editor runs again: edit commit message to describe 4-in-1 reversion]
你可能更喜欢第二种方法,我想我自己也更喜欢,这不是你想要的

关于这一点的旁注:git rebase只是简单地复制,就好像通过使用临时匿名分支来挑选提交一样。要使用符号,请从以下内容开始:

A – C1 – C2 – C3 – C4 – O1 – O2 – O3   <-- branch
其中R是C的倒转。然后,再基础复制原始的R,固定副本,在本例中,该副本最终只是一个提交,我将在再基础开始时调用R,并移动分支标签,使其指向新提交的最后一个,从而使临时分支再次永久:

                                     R4 - R3 - R2 - R1   [abandoned]
                                    /
A – C1 – C2 – C3 – C4 – O1 – O2 – O3 - R   <-- branch
R1到R4会发生什么变化?他们被遗弃了,最终被垃圾收集起来

1除非使用-boundary,否则将使用-in git rev list输出标记边界提交。我还没有用git revert测试过这一点:在图中向后移动一次提交的hat后缀就足够了,我通常在这些情况下使用它。如果达到根提交,它将失败,但这里不会发生这种情况

2不仅仅是因为这些特定的提交哈希对于我运行这些命令的存储库是唯一的。你的散列将是不同的;或者可以使用相对名称,如HEAD~6^..HEAD~3或等效的HEAD~7..HEAD~3。这假设您绘制的提交图片段是准确的,并且从那个以后您再也并没有做过任何移动头部的事情


3旧提交仍然可以通过HEAD和您的分支的重登录找到。默认情况下,这将使它们保留30天,之后旧的reflog条目过期并被删除,然后git gc(包括git根据需要自动执行的任何操作)将删除这些提交。

如果O提交是由其他人进行的,更改C提交意味着您正在重写存储库的历史记录。如果存储库是公共的,则从不特别建议这样做。你确定这就是你想要做的吗?@LucasSaldanha我不会改变C提交。我只希望在历史记录的末尾有一个R提交,表示恢复所有C提交。O的提交与C的提交无关。啊,现在我明白了。我相信@durek给了你一个正确的答案:非常感谢您对这些选项进行如此彻底的比较!非常有用。
                                     R4 - R3 - R2 - R1   [abandoned]
                                    /
A – C1 – C2 – C3 – C4 – O1 – O2 – O3 - R   <-- branch