如何保存 repo 中的当前更改、返回到旧提交、返回到最近的提交以及恢复更改?

How to save current changes in repo, go back to an old commit, go back to most recent commit, and restore changes?

场景

长话短说,我需要返回到 运行 一些代码的旧提交,但我最终想返回到最近的提交。但是,我做了一些我还没有准备好提交的更改。

出于这个原因,我想隐藏我当前的更改,然后回到旧的提交,做我需要做的,然后回到最近的提交,并恢复我最初所做的更改。

注意:这都在一个分支上

问题

执行此操作的最佳方法是什么?

我的想法

我想做这样的事情:

git stash push
git checkout <old_commit_hash>
#Do some stuff
git checkout <most_recent_commit>
git stash pop

另一个想法是提交我当前的更改。最终,当我 return 进行此提交时,我可以创建另一个提交来完成我的工作,然后使用 git rebase 将它们压缩到一个新的提交中。

你可以做你提到的两件事中的任何一件(对更正 eftshift0 mentioned in a comment 取模)。不过,我个人建议尽可能避免 git stash;它有太多的角落案例和棘手的问题。 Committing now 有很多值得推荐的。

不过,无论我现在是否进行提交,我会做的是使用 git worktree add 在旧提交处创建一个分离的 HEAD 工作树。这使您现有的工作不受干扰。新的工作树与单独 git clone 和 运行 git checkout <em>hash</em>[=45= 一样好],有两点不同:</p> <ul> <li>您不必单独制作 <code>git clone,并且

  • 添加的工作树实际上使用当前的Git存储库,所以Git禁止它在同一个分支 作为主要工作树,但共享其他 Git 项。
  • 特别是,git stash push(创建新的存储)或 git checkout -b(创建新的分支)在共享存储库中工作,创建存储或分支名称,您可以从任一工作树中查看。这有各种正面和负面的影响,但总的来说它很小。不过,额外的工作树可以让你构建和 运行 旧的提交——在分离头模式下——并完成你需要做的事情,而不会弄乱你当前的工作树,所以你可以留下正在进行的事情,临时文件、输入、输出等等,如果有用的话,把它弄得乱七八糟。如果有用的话,您还可以将添加的工作树与输入和输出混在一起:这些是单独的工作树(本地文件系统上的不同目录树),因此它们不会相互干扰。

    一个警告:在使用 git worktree add 之前,确保您的 Git 至少是 2.15 版。如果您的 Git 早于 2.5,则您根本没有 git worktree,您需要升级 Git。如果您的 Git 版本为 2.14 或更低版本,请确保在两周内完成 添加的工作树中的所有操作,然后将其删除。

    有关 git worktree 的详细信息,请参阅 its documentation。一个简单的 git worktree add --detach ../old-commit a123456 就可以检查旧提交 a123456。 (从技术上讲,您不需要 --detach,但我喜欢在这里明确表示的想法。)