如何 "reopen" 一个古老的提交到最近提交中恢复的工作树?

How to "reopen" an ancient commit into worktree that was reverted in a recent commit?

我的目标是重新审视旧错误提交的原始更改(此后已恢复),但是由于许多事情已经更改,因此在我的工作树中将那些古老的更改放在 repo 的 HEAD 中,解决问题,然后提交一个新的更好的提交 sans 问题。

一千次提交前(一个月前),我提交了一个更改。

一百次提交前(一周前),有人发现提交有一个微妙但不可接受的问题,以便快速解锁那个人我恢复了提交(git revert hash ... 工作就像魅力)。

一个 sprint 已经过去,现在在我的 repo 的 HEAD,我想重新打开原始提交中已经被还原的更改,这样我就可以梳理这些更改并找出根源发现问题的原因。

将一千次提交之前的提交“重新打开”到我的本地工作树中的好方法是什么?(因此 git status 将是 在我的工作树中修改。)

更糟糕的情况是 git checkout 在另一个 repo 中并排提交旧的提交并进行手动差异(例如,vi -d current/foo.cpp ancient/foo.cpp)并手动复制差异。听起来很乏味,而且手动错误的可能性更高。

会有一些冲突,但它们相对微不足道,例如固定的拼写错误或空格更改。

我不想按原样重新提交旧提交,因为它需要仔细检查和修复。

我建议在您的日志历史记录中找到 还原提交 的散列,然后使用此 <commit_hash> 您可以

git revert --no-commit <commitHash>
# or the shorter
git revert -n <commitHash>

...这会将原始提交的更改带入您的工作树,而无需实际提交,这使您可以测试、编写更多代码,然后在您准备好时提交。

您已经有了一个 ,但我认为扩展该答案并突出您问题中的特定要点将很有价值:

I do not want to re-commit the ancient commit as-is, because it needs to be scrutinized and fixed.

意识到 Git 想要 你做出承诺是很重要的; Git 喜欢 承诺,你也应该这样做! (我在这里只是半开玩笑。)倾向于提交的原因是,一旦您提交,您就锁定了该更改(仅限本地机器),如果您决定不提交,将来可以轻松取回它使用它,但稍后会改变主意。所以我建议将那句话中的心态调整为类似于:

I do not want my final version to have the ancient commit as-is, because it needs to be scrutinized and fixed.

这里的细微差别是你处于黑客模式,你还不知道最终版本是什么样子。所以我会推荐你​​do 按原样提交旧提交(在解决冲突后)。然后你可以修改那个提交,或者添加一个新的提交和你的修复,然后将这两个提交压缩成一个提交。最终结果与您没有首先“提交”原始提交(使用 --no-commit 选项)是一样的,但是如果您这样做,则可以更轻松地撤消您的尝试回到起点需要。

因此,我建议的解决方案是,如果您从 HEAD 开始(在新分支或同一分支中),其中任何一个都会产生相同的结果:

  1. 还原还原提交。
  2. Cherry-pick 已还原的原始提交。

此时您可能会遇到冲突。我的建议是解决它们,然后 --continue 还原或挑选以创建新提交。现在您可以破解修复,并可能将该修复放入新的提交(或修改以前的提交)。经过更多测试和调整后,您可以再次修改或使用最终调整进行第三次提交。满意后,如果您有多个提交想要作为一个呈现给共享存储库,请将这 3 个提交压缩为一个并将其推出。

显然这只是个人喜好。如果你想违背 Git 的原则并限制本地提交,你当然可以。 --no-commit 选项存在,并且可用于 cherry-pickrevert 命令。但是 --no-commit 选项存在的主要原因是当你要恢复或挑选一系列的多个提交时,你希望将它们放在一起成为一个提交。 (如果没有该选项,您将不得不创建多个提交,然后自己手动将它们压缩成一个,这样效率更高。)对于您的特定用例,我不会在此处推荐 --no-commit。也许一个好的经验法则可能是:

Use the --no-commit option when you know exactly what change you are going to make afterwards, and you intend to commit the change shortly after running the command.

深思...