如何“重新打开”在最近提交中恢复的工作树中的古代提交?
Posted
技术标签:
【中文标题】如何“重新打开”在最近提交中恢复的工作树中的古代提交?【英文标题】:How to "reopen" an ancient commit into worktree that was reverted in a recent commit? 【发布时间】:2021-12-09 03:32:39 【问题描述】:我的目标是从旧的错误提交中重新访问原始更改(此后已被还原),但是由于许多事情都发生了变化,因此在我的工作树中将这些古老的更改保存在 repo 的 HEAD 中,修复问题并提交新的更好地提交 sans 问题。
一千次提交前(一个月前),我提交了一个更改。
一百次提交前(一周前),有人发现了一个微妙但不可接受的提交问题,以便快速解除对那个人的阻止,我恢复了提交(git revert hash
... 就像一个魅力)。
一个 sprint 已经过去,现在在我的 repo 中的 HEAD,我想重新打开原始提交中已经恢复的更改,以便我可以梳理更改并找出根本原因发现的问题。
有什么好方法可以将一千次提交之前的提交“重新打开”到我的本地工作树中?(所以 git status
将在我的工作树。)
更糟糕的情况是 git checkout
在另一个 repo 中并排提交旧的提交,然后手动进行差异(例如,vi -d current/foo.cpp ancient/foo.cpp
)并手动复制差异。听起来很乏味,而且手动出错的可能性更高。
会有一些冲突,但它们会相对微不足道,例如固定的错别字或空白更改。
我不想按原样重新提交古老的提交,因为它需要仔细检查和修复。
【问题讨论】:
如果我理解你的话,你可以创建一个临时分支,选择提交,对之前的提交进行软重置。比隐藏当前的更改。签出当前工作分支,然后应用存储。这是你想要达到的目标吗? @MartinTavernier • 这听起来很合理。我自己不会想到这一点(我的 git-fu 很弱)。我会试一试并报告,谢谢! 【参考方案1】:我建议在您的日志历史记录中找到 revert commit 的哈希值,然后使用 <commit_hash>
您可以
git revert --no-commit <commitHash>
# or the shorter
git revert -n <commitHash>
...它将原始提交的更改带入您的工作树,而无需实际提交,这使您可以测试、编写更多代码,然后在您准备好时提交。
【讨论】:
这听起来比 Martin 的建议还要简单。我什至没有考虑恢复还原提交的角度。我先试试这个。 好吧,我在我的 repo 上对其进行了测试,它似乎工作得很好,这将在未来很好地为我服务,谢谢 ;) @MartinTavernier 感谢您的反馈。我已经使用这个过程很长一段时间了,到目前为止,这是我在这种情况下找到的最简单/最清晰的方法。 我需要一段时间才能找到潜伏的错误。无论如何,我可以看到这让我达到了我想要的状态。Huzzah!谢谢谢谢! (也感谢 Martin 的建议。)【参考方案2】:您已经有一个working solution,但我认为扩展该答案并突出您问题中的特定点会很有价值:
我不想按原样重新提交古老的提交,因为它需要仔细检查和修复。
意识到 Git 希望你做出提交是很重要的; Git loves 提交,你也应该这样做! (我在这里只是在开玩笑。)倾向于提交的原因是,一旦你提交,你就锁定了那个更改(仅限于你的机器上),如果你决定不做,将来可以很容易地取回它使用它,但稍后改变主意。所以我建议将这句话中的心态调整为类似于:
我不希望我的最终版本按原样保留古老的提交,因为它需要经过审查和修复。
这里的细微差别是您处于黑客模式并且您还不知道最终版本的外观。因此我建议您做提交古老的提交(在解决冲突之后)。然后你可以修改那个提交,或者在你的修复中添加一个新的提交,然后将这两个提交压缩成一个提交。最终结果与您一开始没有“提交”原始提交(使用--no-commit
选项)相同,但是如果您需要,这样可以更轻松地继续撤消您的尝试回到起点.
因此,我建议的解决方案是,如果您从 HEAD 开始(在新分支中或在同一分支中),则其中任何一个都会产生相同的结果:
-
还原还原提交。
Cherry-pick 已还原的原始提交。
此时您可能会遇到冲突。我的建议是解决它们,然后--continue
revert 或cherry-pick 来创建新的提交。现在您可以破解修复程序,或许可以将该修复程序放入新的提交中(或修改之前的提交)。经过更多的测试和调整后,您可以再次修改或使用最终调整进行第三次提交。满意后,如果您希望将多个提交作为一个提交到共享存储库,请将这 3 个提交压缩为一个并将其推出。
显然这只是个人喜好。如果你想违背 Git 的原则并限制本地提交,当然可以。 --no-commit
选项存在,它可用于cherry-pick
和revert
命令。但是--no-commit
选项存在的主要原因是当您恢复或挑选一系列多个提交时,您希望将它们放在一起成为一个提交。 (如果没有该选项,您必须创建多个提交,然后自己手动将它们压缩为一个,因此这样会更有效。)对于您的特定用例,我不建议在这里使用--no-commit
。也许一个好的经验法则可能是:
如果您确切知道之后要进行什么更改,并且打算在运行命令后立即提交更改,请使用
--no-commit
选项。
深思……
【讨论】:
以上是关于如何“重新打开”在最近提交中恢复的工作树中的古代提交?的主要内容,如果未能解决你的问题,请参考以下文章