首页 > 解决方案 > 物体松动的原因是什么?`git prune` 可以安全地删除它们吗?

问题描述

我正在使用使用我们公司的 SVN 存储库作为来源的本地 Git 存储库。

我经常收到这样的信息:

错误:最后一次 gc 运行报告了以下内容。请更正根本原因并删除 .git/gc.log。在删除文件之前不会执行自动清理。

警告:无法到达的松散对象太多;运行 'git prune' 删除它们。

确实删除.git/gc.loc和调用git prune解决了这个问题。然而,Michael Donohue
在对VonCHow to skip "Loose Object" popup when running 'git gui'回答的评论中指出:

[...] 我确实喜欢将松散物体放置两周的安全方面,如果我想回去看看一些旧的修订 [...]

在对Whole team 的回答(也由VonC撰写)中,Jlengrand收到了“太多无法访问的松散对象”消息——一个关于问题与从 SVN 移动到 git 后的松散对象有关的问题——由jlengrand 撰写VonC写道:

  • 运行 git prune 并祈祷它没有破坏东西(谢天谢地没有)

所以,我认为git prune这是一个可以破坏事物的危险操作。

为了安全地处理“太多无法到达的松散对象”消息,我有以下问题:

是什么导致了这些松散的对象(请参阅man git-fsckunreachable object 并查看torek回答——关于 git 对象和哈希的内部工作原理以及git gc,git prunegit repack——当我们这样做时 git 会做什么:git gc - Lyes CHIOUKH的git prune )?
仅仅是这样吗git svn push

  1. 读取 git commit 对象,
  2. 将其发送到 SVN 服务器,
  3. 检索存储的 SVN 修订版,
  4. 创建一个反映 SVN 版本的新 git commit 对象,
  5. 将指向第 1 步提交的 HEAD 指针替换为指向第 4 步提交的指针,并且
  6. 将原始提交保留为松散对象。

这确实会导致松散的提交吗?
这是否会导致所有松散的提交(我还对 SVN 中尚未使用的东西进行一些 git 树操作,例如git stashgit cherry-pickgit rebasegit reset)?

我什么时候需要这些松散的物品?git prune在我的个人 git repo 上使用的好策略是什么?

标签: gitgit-svn

解决方案


在 Git 中,所有新对象都以“松散”对象开始。(我完全不清楚为什么你会收到太多错误。)

有一个管道命令,git hash-object可以创建任何类型的新对象。其他命令本质上是git hash-object为他们需要的对象类型构建的,例如,git write-tree使用索引创建一些树对象,并git commit-tree创建一个提交对象。使用git add为每个添加的文件创建一个松散对象;显然在某些情况下,这可能是很多对象。

因此,创建大量松散对象非常容易,但通常,执行此操作的 Git 命令也会运行git gc --auto以自动打包它们。将它们安全打包后,git prune取出松散的:

所以,我认为git prune这是一个可以破坏事物的危险操作。

这并不是特别危险,只要您在不做任何其他事情的情况下运行它(即,不运行任何可能会主动创建松散对象的 Git 命令)。添加--expire 14.days.ago使它保留最近创建的松散对象,这就是git gc它所做的 - 好吧,它使用您的gc.pruneExpire设置,但默认为14.days.ago.

如果您正在积极地使用 Git 本身,并在打包程序中引入了一个错误,那么它就会变得很危险。:-) 基本上,每当您删除冗余时,您都需要确保它实际上是冗余的。


推荐阅读