如果没有存储并且您已经过期了 reflog,那么假设可以从某些 ref 访问提交似乎是合理的——但并非所有 ref 都是分支。
你可以试试这个:
git for-each-ref --format='%(refname)' |xargs -I {} git rev-list {} --format="%H {}" |grep ^<hash>
<hash>
您要摆脱的提交的 ID 在哪里。在一个简单的测试中,我跑了
git for-each-ref --format='%(refname)' |xargs -I {} git rev-list {} --format="%H {}" |grep ^80c0ab
并得到像
80c0ab39850d7b3ef4969ab934d834f22959a317 refs/original/refs/heads/master
告诉我,我的目标提交由下面的 ref 保持活动状态refs/original
- 在这种情况下,由git filter-branch
更新- 基于评论的一些后续行动。
您注意到上面的命令返回refs/stash
,但存储列表 (per git stash list
) 是空的。
问题是,存储列表使用了经过大量操作的 reflog。还有你用来清除 reflogs 的命令
git reflog expire --expire=now --all
将破坏密钥 reflog。所以现在stash
命令不知道该做什么并且表现得好像没有存储,但是stash
ref 仍然存在,保留最新存储中的任何内容(或从创建该存储的提交可访问的完整提交历史)在当地活着[1]。
IMO 可以被认为是一个错误。默认情况下,计划的 reflog 到期不作任何stash
处理(因为……嗯……这个原因)。也许您的论点是您特别说过要使所有reflogs 过期,但我认为“除 the 之外的所有 reflogs ”在这种情况下stash
将是一个更有用的定义。--all
好吧,随便。
如果你确定你不关心被藏起来的东西
git update-ref -d refs/stash
然后继续你的清理工作。
[1] “本地活动”,因为至少默认情况下stash
不共享。克隆 repo 或将其 refs 推送到空的遥控器中,很可能不会携带有问题的提交。但是,这取决于 git 将发送最小包的假设 - 并且 AFAIK 不能保证这样做。因此,如果您需要提交消失,那么最安全的做法是达到它在本地不存在的点,然后从该干净的本地 repo 重建任何遥控器(等)。