git清理
在我的日常工作以及此博客中,我经常使用Git。 使用它时,我经常在推送之前将其本地化,以获取清晰易读的历史记录。
样本工作流程
对于我的博客,分支模型如下所示:
o---o---o---o master \ \---o---o feature/newposts
-
主
-
不出所料,此分支是生产站点。
功能/新闻
-
该分支专门用于新职位。 每次提交有一篇帖子。
另外,为了加快渲染速度,只有少量最新帖子。 master之后的第一个提交是删除其中的大多数。
要发布新帖子,我从feature/newposts
到master
分支。 另外,当我对master
进行更改时,我会将feature/newposts
到master
,以获取最新更新。
改基的影响
当我交互式地基于master
时,事情开始变得有趣起来。
- 初始状态
A---B---C---D master \ \---a---b feature/newposts
- 交互地基于母版
A---B---C---D \ \ \ \---a---b feature/newposts \ \---D' master
- 重新掌握
A---B---C---D \ \--C'---D' master \ \---a---b feature/newposts
看到提交C
和D
吗? 注意,它们没有被任何分支引用,并且它们不与git log
显示。 仍然可以通过git reflog
显示它们。
同样,这些提交也不会显示在GUI(例如SourceTree)中。
晃来晃去的提交
是时候进行一些定义了:
无法到达的物体
- 悬空物体
无法从分支,标签或任何其他引用访问的对象。
不可到达的对象,即使从其他不可到达的对象也无法到达; 悬挂对象没有来自存储库中任何引用或对象的引用。
https://git-scm.com/docs/gitglossary/
使用这些定义,上图中的提交C
和D
被认为是不可访问的,因为没有引用指向它们中的任何一个。 而且,提交D
也是悬空的 ,因为没有其他对象引用它,而提交C
并不是因为D
指向它。
要列出那些悬空和无法到达的对象,可以使用git fsck
命令:
git-fsck-验证数据库中对象的连接性和有效性
https://git-scm.com/docs/git-fsck
例如,要显示无法访问的提交:
git fsck--unreachable
如果未显示预期的提交,则可能是因为reflog引用了该提交。 在这种情况下,可以选择忽略reflog引用。
git fsck--unreachable--no-reflog
相同的命令只能用于列出悬空提交。 用--dangling替换--unreachable。
清理正确
Git在存储文本方面非常有效。 但是,毫无意义的是既不能存储刷新日志,也不能存储超过一定时间的提交。
Git中有一个垃圾收集器。 它可能会沿着某些命令自动运行。 您会知道当出现以下输出时,GC已运行:
Counting objects: 9451, done. Delta compression using up to 8 threads. Compressing objects: 100% (4657/4657), done. Writing objects: 100% (9451/9451), done. Total 9451 (delta 3843), reused 8900 (delta 3584)
也可以显式运行它:
git gc
调用GC将删除无法访问的对象。
GC不仅删除无法访问的对象,而且还压缩文件修订
但是,请记住,大多数未使用的对象仍由引用日志引用。 因此,它们不会被视为不可访问的,因此也不会被垃圾收集。 现在的问题是如何使reflog过期以使对象无法访问?
Reflog到期
要使reflog过期,请运行:
git reflog expire
刷新日志在标准和不可访问之间分开:
标准 | 无法到达 | |
---|---|---|
Expired after (by default, days) | 90 | 30 |
Command parameter |
|
|
例如,要使超过两个星期的更新而不是默认的90天值过期,请使用:
git reflog expire--expire= 2.weeks.ago
在reflog过期后,相关的提交真正变得不可访问,并且最终可以被垃圾收集器删除。
结论
这篇文章探讨了提交如何在Git中相互引用,以及如何清除它们。 但是,在大多数情况下,默认的定期自动清除就足够了。 请记住,通过删除引用和提交,您将更难从错误中恢复。
git清理