首页 > 解决方案 > 重写 git 历史记录时,如何应用将所有内容返回到其先前状态的提交?

问题描述

通常我想分解一个大的提交:

git commit -a -m "Monolith"

我知道如何拆分提交(git gui是我的朋友),但有时我实际上想手动修改它......

git branch temp          # Keep a reference to all my hard work
git reset --hard HEAD~   # Rewind 'my-topic' branch

# hack hack
git commit -a -m "Refactor 1"
# hack hack
git commit -a -m "Refactor 2"

为了完成它,我想应用另一个提交,将代码恢复到存储在 branch 中的状态temp,通常包括原始提交消息。

是否有捷径可寻?

我想象一个合并策略cherry-pick可能会完成工作,但可惜这些都没有:

  git cherry-pick --strategy=theirs temp   # I am told about conflicts
  git status                               # ... But here I find no changes to commit!
  git cherry-pick --strategy=ours temp     # Worth a try. Nope, empty commit.
  git cherry-pick --strategy=recursive --strategy-option=ours temp  # Partial result, bits are missing

我知道实现这一目标的一种方法:

git log -1 temp # note the SHA
git checkout temp
git reset --soft my-topic
git commit -C <SHA-from-above>  # branch 'temp' now contains the desired commit
git checkout HEAD -B my-topic
git br -d temp

然而,这似乎是一种非常容易出错的方法。任何小错误和我想要保留的提交可能不在任何分支中(git reflog救援......)。我想找到一些更合乎逻辑且更容易记住/做的事情。

标签: git

解决方案


要在 处重新创建树temp,(至少)有两种相当简单的方法:一种是

git checkout temp -- .

另一个是

git diff temp | git apply --index

之后,您使用相同的提交消息创建提交

git commit -C temp

这两种选择各有利弊。该checkout路由不会删除不再存在的文件temp。该apply路由不适用于二进制文件。

旁注:使用现代 Git,您可以使用git restore代替git checkout,但我是老前辈,还没有学会使用它。


推荐阅读