git - 重写 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
救援......)。我想找到一些更合乎逻辑且更容易记住/做的事情。
解决方案
要在 处重新创建树temp
,(至少)有两种相当简单的方法:一种是
git checkout temp -- .
另一个是
git diff temp | git apply --index
之后,您使用相同的提交消息创建提交
git commit -C temp
这两种选择各有利弊。该checkout
路由不会删除不再存在的文件temp
。该apply
路由不适用于二进制文件。
旁注:使用现代 Git,您可以使用git restore
代替git checkout
,但我是老前辈,还没有学会使用它。
推荐阅读
- python - 如何确定列表中的哪些元素是整数,哪些是字符串?
- java - 通过其他唯一值而不是使用 Hibernate 的主键更新 DB 中的行?
- python - 如何控制reportlab表中的浮点数精度?
- azure-sql-managed-instance - 重命名作为异地复制一部分的 Azure SQL 托管实例上的数据库
- python - 将编码的 csv 从 url 获取到 Pandas
- sql - 我可以在 sql 查询中使用不同的过滤器两次使用同一列吗?
- c# - 如何修复一侧具有两个相同类型实体的一对多关系
- html - 在我的 Angular 应用程序中使用 api 调用值作为 div 的背景图像
- c# - 如何在 UWP 中遍历 ListView?
- php - PHP - 为所有子数组添加默认值