【问题标题】:Git: How to permanently delete a local commit completely from the git databaseGit:如何从 git 数据库中完全永久删除本地提交
【发布时间】:2023-03-08 11:45:01
【问题描述】:

我知道 git reset(包括 --hard),但这并没有完全删除提交,它只是调整了树。我已经探索过 git gc,但这似乎也永远不会永久删除提交。我知道过滤器分支,但这只会从提交中删除文件,而不是提交本身。

围绕这个主题有很多堆栈溢出问题,但我找不到问题的真正答案:如何真正删除本地提交(或一系列提交) ,这样它就不再存在于数据库中的任何地方,就好像它根本没有完成一样?如果它是一种仅限于分支尖端的方法,那就没问题了。

编辑:这是我的错误。我正在使用 gitk 并使用 F5 查看整个树。但是 F5 执行“更新”,而 shift-F5 执行“重新加载”。除非您通过按 shift-F5 完全重新加载,否则删除实际上并不会真正显示出来。

【问题讨论】:

标签: git


【解决方案1】:

如果你的分支是这样的:

A   <-- HEAD
|
B
|
C   <-- to be removed
|
D

如果您想删除提交 C,以下命令可能对您有所帮助:

git rebase -i D     # if you have D's sha1 handy
# OR
git rebase -i C^    # parent of C (which is the same as D in this simple example)

发布后,会弹出一个编辑器,其中包含从D 的子项开始的所有提交,即待办事项列表中的ABC。只需在该编辑器窗口中删除带有 commit C 的行并保存文件。

【讨论】:

  • 这不会删除原始提交。他们仍然会在那里。我尝试了那个确切的场景。 rebase 只是成为另一个分支,但如果你查看整个树,旧的提交仍然存在。
  • @Nairebis 你在哪里看的?吉特克?按 SHIFT-F5(重新加载)。您讲述了 local 提交。你已经推他们了吗?然后push -f
  • 嘎!你完全正确......我使用的是 Gitk 并使用 F5 而不是 shift-F5。我做了一个shift-F5,他们消失了。该死。
  • :-) 很高兴听到。但请注意:提交仍然存在,但如果您不知道它们的 SHA1,则无法轻松访问它们。它们受到垃圾收集的影响。所以运行git gc --prune=now 来清除它们的所有痕迹(或者等待 30 天左右,直到它们被自动 gc'ed)。
【解决方案2】:
  1. 使用resetrebase,甚至filter-branch,使提交无法从任何 ref 或标签访问。 (如何使用过滤器分支到remove the file from all branches).
  2. 使 reflog 过期,以便无法从那里访问提交。 git reflog expire --expire=now --all
  3. git prune 从数据库中删除无法访问的对象。 (git gc --prune=all 也可以做到这一点,但git gc plain 会保留不到两周大的松散物体)。
  4. 您可以通过手动检查 git 对象存储来验证它是否真的消失了。一个 git 对象是根据其 SHA1 哈希值存储的。哈希的前两个字母是一个目录,最后 38 个是该目录内的文件名。

因此,如果您的问题提交的 SHA1 哈希是 12345ABCDEF...,那么它将位于 .git/objects/12/345ABCDEF...

如果您真的很偏执,您可以找出您担心的特定 blob(文件内容)的 SHA1 哈希值,并使用 git hash-object &lt;filename&gt; 对其进行哈希处理,然后检查数据库中的该哈希值。

【讨论】:

    猜你喜欢
    • 2012-07-01
    • 2019-11-14
    • 2013-05-09
    • 1970-01-01
    • 2013-08-03
    • 2015-11-05
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    相关资源
    最近更新 更多