git - 如何找到新的强制推送提交 ID 覆盖的预提交 ID?
问题描述
我将代码更改添加到 repo,我可以通过git log -n1
.
然后我结合一个新的变化来预先提交 id 使用git add -u; git commit --amend; git push -f
.
然后我突然忘记了第二次更改的区别是什么。但是 pre-commit id 在git log
历史上消失了。
如何找到丢失的提交?
解决方案
TL;DR:使用 reflogs。
长
该git commit --amend
操作具有“将旧提交推到一边”的效果。如果我们绘制提交,通过分支名称找到,我们会得到这样的图片:
... <-F <-G <-H <--branch
这里的每个大写字母都代表一个 Git 提交哈希 ID。在这种情况下,分支名称包含最新提交branch
的哈希 ID ,因此:H
git rev-parse branch
打印出这个哈希 ID。Git 能够使用这个存储的哈希 IDH
从提交数据库中读取提交。
提交H
本身在其元数据中存储了早期提交的原始哈希 ID G
。因此,H
从数据库中读取后,Git 可以找出这个哈希 ID,并使用它G
从数据库中检索提交。
检索G
后,Git 具有来自 的元数据G
,它给出了较早提交的哈希 ID F
,因此 Git 可以F
从数据库中检索提交。这当然有元数据,包括另一个更早提交的哈希 ID,等等。
当我们以正常方式添加新提交时,Git 所做的是:
- 为新提交写出一个新快照(我们称之为新提交
I
,使用字母表的下一个字母)。 - 写出提交的元数据
I
:我们的姓名、我们的电子邮件地址、当前日期和时间等等。在此元数据中,Git 包含当前commit的哈希 IDH
,作为 commit 的父级I
。 - 使用内部版本
git commit-tree
将所有这些作为新提交写入对象数据库。编写提交的行为会产生新的哈希 ID:我们将调用I
. - 将提交的哈希 ID 存储
I
在当前分支名称中。
第 4 步导致branch
指向新的提交I
,而不是现有的提交H
。当我们绘制结果时,我们有:
... <-F <-G <-H <-I <--branch
如您所见,从最后开始并向后工作的过程现在将找到 commit I
,然后是 commit H
,然后是 commit G
,依此类推。
这样做git commit --amend
是通过将新的提交点直接返回到当前提交的父级来绕过当前提交。在这种情况下,由于指向,Git 会将新的提交直接指向:I
H
G
I
G
H
/
... <-F <-G <-I <--branch
无论如何,提交H
确实存在一段时间。但无处可找到其哈希 ID。如果它还在你的屏幕上,或者在一个窗口的回滚中,你可以这样抓取它:Git需要哈希ID;分支名称只是提供哈希 ID 的一种方式。如果您可以剪切并粘贴哈希 ID,那就可以了。
但这就是上面reflog这个词的含义。每当 Git替换存储在分支名称或特殊名称中的值时HEAD
,Git都会将先前的值保存在日志中。 此日志是可选的,但对于您的存储库,它默认为“开启”(至少如果您使用传统的 Git;如果您使用的是 Eclipse 或 JGit 或其他仅使用相同数据库格式的非 Git 程序,则无法保证)。因此,当两者都git commit
覆盖git commit --amend
存储在分支名称中的哈希 ID 时,它们会将先前的哈希 ID 保存在日志中。
不带参数运行git reflog
将转储HEAD
. 这是最活跃的 reflog,其中包含最多的“内容”,因此它有更多信息需要筛选。
运行git reflog branch
,如果你在一个名为的分支上branch
,转储 reflog 为branch
. (如果您使用main
or master
,请使用git reflog main
or git reflog master
。)这将显示对该分支名称的更新。
在这两种情况下,您都可以在git commit --amend
. 这将是被推开的提交的哈希 ID。所以你现在可以运行:
git diff <hash> HEAD
例如比较两个提交。
还有其他方法可以使用 reflog。请参阅文档git reflog
和编写修订 ID 表达式的文档。
推荐阅读
- matlab - Findpeaks 预计 X 的价值会增加
- typescript - 返回子类作为超类的类型
- python - Spotipy 用户播放列表删除曲目问题
- swift - Swift - 当需要满足所需的初始化程序时,如何初始化子类中的属性?
- android - 我如何“带来”以“前面”为中心的选定视图?
- java - 在java中解析一个SQL语句拆分条件
- symfony - 外键(不想编辑)错误
- android - 我如何解决在android的片段中集成谷歌地图
- java - 无法在 jxbrowser-java 中设置地理定位权限
- vuejs2 - 如何在 Vuetify 中为图像制作材质框