确定阻止提交从git中删除的内容

XDR*_*XDR 3 git git-gc git-commit git-reflog

如何通过以下命令确定阻止提交被git修剪的内容?

git reflog expire --expire=now --all

git gc --prune=now
Run Code Online (Sandbox Code Playgroud)

细节

我想XYZ从我的克隆中完全删除提交(例如,提交哈希).如果以上不是正确的命令(或者如果以下任何命令/扣除不正确),请告诉我.

我知道XYZ在运行上面的剪枝后仍然在我的克隆中,因为以下内容返回日志列表:

git log XYZ
Run Code Online (Sandbox Code Playgroud)

我知道这XYZ不在任何分支中,因为以下输出没有:

git branch --contains XYZ
Run Code Online (Sandbox Code Playgroud)

我认为这XYZ不是任何存储因为以下输出没有:

git stash list
Run Code Online (Sandbox Code Playgroud)

XYZ然而,实际上是在藏匿,但git bug阻止了藏匿列表.

Mar*_*ger 8

如果没有存储并且你已经使reflogs过期,那么假设可以从某些ref中访问提交似乎是合理的 - 但并非所有引用都是分支.

你可以试试这个:

git for-each-ref --format='%(refname)' |xargs -I {} git rev-list {} --format="%H {}" |grep ^<hash>
Run Code Online (Sandbox Code Playgroud)

<hash>你想要摆脱的提交的ID 在哪里.在一个简单的测试我跑了

git for-each-ref --format='%(refname)' |xargs -I {} git rev-list {} --format="%H {}" |grep ^80c0ab
Run Code Online (Sandbox Code Playgroud)

得到的输出就像

80c0ab39850d7b3ef4969ab934d834f22959a317 refs/original/refs/heads/master
Run Code Online (Sandbox Code Playgroud)

告诉我,我的目标提交由一个ref保持活着refs/original- 在这种情况下是由...创建的预重写"备份引用"git filter-branch


更新 - 根据评论进行一些跟进.

您注意到上面的命令返回refs/stash,但存储列表(每个git stash list)为空.

问题是,存储列表使用了大量操作的reflog.以及用于清除reflog的命令

git reflog expire --expire=now --all
Run Code Online (Sandbox Code Playgroud)

将摧毁关键的reflog.所以,现在的stash命令,不知道做什么,像有没有藏匿,但是stash裁判确实还存在,从最近的藏匿保持任何东西(或完整的提交历史,从承诺在其上创建了藏匿可达)在当地活着[1].

IMO可能被认为是一个错误.默认情况下,计划的reflog到期stash单独留下(因为......好吧......这个原因).也许这个论点认为你明确地说过期所有的 reflogs,但我认为"除了stash" 之外的所有reflogs --all在这个例子中都是一个更有用的定义.

好吧,无论如何.

如果你确定你不关心被藏起来的东西

git update-ref -d refs/stash
Run Code Online (Sandbox Code Playgroud)

然后恢复你的清理工作.


[1]" 本地活着",因为至少在默认情况下stash不会共享.克隆存储库或将其refs推入空的遥控器很可能不会带来违规的提交.然而,这取决于git将发送最小包的假设 - 而AFAIK并不保证这样做.因此,如果您需要提交,那么最安全的事情是到达本地不存在的点,然后从该干净的本地存储库重建任何遥控器(等).