如何收缩.git文件夹

JMW*_*JMW 112 git

我目前的基数总大约是.200MB.

但我的.git文件夹有5GB(!)的惊人大小.因为我把我的工作推到外部服务器,我不需要任何大的本地历史......

如何缩小.git文件夹以释放笔记本上的一些空间?我可以删除超过30天的所有更改吗?

非常感谢任何帮助:)

kni*_*ttl 93

你不应该删除超过30天的所有更改(我认为它可能在某种程度上利用git,但实际上不推荐).

你可以调用git gc --aggressive --prune,它将在你的存储库中执行垃圾收集并修剪旧对象.你有很多经常改变的二进制文件(档案,图像,可执行文件)吗?那些通常导致巨大的.git文件夹(记住,git存储每个修订版本的快照和二进制文件压缩很严重)

  • 实际上,`git gc --aggressive`被认为是不好的做法.最好使用`git repack -a -d --depth = 250 --window = 250`. (21认同)
  • @ knittl:绝对的.以下是Linus本人的致辞:http://gcc.gnu.org/ml/gcc/2007-12/msg00165.html (12认同)
  • @ Artefact2您的陈述[已过时](http://comments.gmane.org/gmane.comp.version-control.git/203033):*请注意该帖子的年龄.实际上,在发布的同一天,邮件列表上的讨论导致了这个提交:[..]因此,对于这两种方法,包装参数现在都是相同的.*.`--prune`也没有必要,因为它自`v1.5.5-rc0`(commit [25ee973](https://github.com/git/git/commit/25ee973),2008年3月)成为默认值. (12认同)
  • 它有什么作用? (4认同)
  • @ artefact2:感谢您的链接!我已阅读它,并且linus指出,-aggressive不会重用(好的)增量-在此问题中似乎不存在,因为存储库很大。使用重新打包的方式实际上将花费更长的时间。git gc --aggressive调用repack,窗口大小为250(参见手册页),深度为250(参见源代码)。--aggressive另外添加了-f开关,以丢弃并重做所有以前的增量操作(如链接中所述) (2认同)

Dav*_*han 57

以下是git Linus的创建者关于如何缩小git repo的内容:

相当于"git gc --aggressive" - 但是*正确* - 就是做(过夜)之类的事情

   git repack -a -d --depth=250 --window=250
Run Code Online (Sandbox Code Playgroud)

那个深度的东西只是关于三角链的深度(让旧历史更长一些 - 它值得空间开销),窗口的事情是我们希望每个delta候选者扫描多大的对象窗口.

在这里,您可能希望添加"-f"标志(这是"丢弃所有旧的增量",因为您现在实际上正在尝试确保这个实际上找到了好的候选者.

来源:http://gcc.gnu.org/ml/gcc/2007-12/msg00165.html

这会消除我的回购中孤立的二进制数据吗?"git repack"不会删除您已检入您的仓库然后将其删除的图像或二进制数据.要从您的仓库中永久删除这类数据,您必须重新编写历史记录.一个常见的例子就是你不小心在git中检查你的密码.您可以返回并删除一些文件,但之后您必须重新编写您的历史记录,然后强制将新的repo推送到您的原点.

  • 在本地执行 `repack` 后,进行提交和推送,收缩是否也会远程化? (2认同)
  • 没有帮助。我有 6G 的存储库,在执行此命令后它仍然是 6G。 (2认同)

Chr*_*haw 21

我试过这些,但我的存储库仍然很大.问题是我不小心检查了一些生成的大文件.经过一番搜索,我发现了一个很棒的教程,可以很容易地删除大量生成的文件.本教程允许我将我的存储库从60 MB缩小到<1 MB.

http://stevelorek.com/how-to-shrink-a-git-repository.html

  • [这是一个存档版本](https://web.archive.org/web/20180112163756/http://stevelorek.com/how-to-shrink-a-git-repository.html) 以防链接失效。这个答案对我遇到的一个 repo 有帮助,其中 .exe 和 .zip 文件被提交,这使得 .git 文件夹的大小变得臃肿 (4认同)

Gab*_*les 20

如何缩小 git 存储库中的 .git 文件夹

首先尝试这个

如果您有大量重复数据,请尝试运行git gc。当您有大量相同或相似文件的重复副本时,它有可能节省大量空间。请参阅此处:git 是否会在文件之间删除重复项?,以及我的回答和轶事经验,其中git gc自动将高达 107 GB 压缩到 11 GB。

概括

按照这个顺序,从最不危险和/或最有效和/或最快到更危险和/或不太有效和/或最慢。

请注意,这些git lfs行仅适用于您已git lfs安装的情况。谷歌搜索一下,你会发现它是一个第三方独立应用程序。如果您尚未git lfs安装,请忽略这些行。请参阅我在这个答案下面的评论,从这里开始。另外,如果你不使用git lfs就不要使用。它有可能导致许多问题。例如,我在这里的问题中谈到了这一点。

这些测试结果针对一个存储库,其中du -hs --exclude=.git .显示存储库总大小(不包括.git目录)约为80 GB,并du -hs .git显示.git文件夹开始时约为162 GB

更新:一定要跑time git gc!在文本文件大量重复的情况下,它可以节省大量空间。请参阅此处此处我的答案。

#                                                                   Memory Saved
#                                               Time it took        in .git dir
#                                               ------------        ------------
time git lfs prune                              #  1~60 min          62 GB
time git gc                                     #  3 min            < 1 GB
time git prune                                  #  1 min            < 1 GB
time git repack -a -d --depth=250 --window=250  #  2 min            < 1 GB
# (Note: `--prune` does nothing extra here; `man git gc` says 
# `--prune is on by default`)
time git gc --aggressive --prune                #  1.25 hrs         < 1 GB
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,最后一个命令花费了长的时间,但几乎没有什么好处,所以甚至不要运行它!

另外,运行的另一种方法git lfs prune是手动删除整个.git/lfs目录,然后从头开始重新获取 lfs(git 大型文件系统)内容。
注意:不要意外删除整个.git目录!您将丢失此存储库的所有 Git 历史记录、分支和提交!仅删除.git/lfs目录。像这样的事情可能会起作用:

# 1. Delete the whole git lfs directory
rm -rf .git/lfs


# 2. Re-fetch the git lfs contents again from scratch.
# See my answer here: https://stackoverflow.com/a/72610495/4561887

# Option 1 (recommended): fetch (to the ".git/lfs" dir) AND check out just the
# git lfs files for just the one branch or commit you currently have
# checked-out. 
# - this might download ~20 GB of data on a large corporate mono-repo
git lfs pull
# OR do this (these two commands do the exact same thing as `git lfs pull`)
git lfs fetch
git lfs checkout

# Option 2: fetch (to the ".git/lfs" dir) ALL git lfs files for ALL branches on
# the remote
# - this might download ~1000 GB of data on the same large corporate mono-repo
#   as above
git lfs fetch --all
# Also check out, or "activate" the git lfs files for your currently-checked-out
# branch or commit, by updating all file placeholders or pointers in your
# active filesystem for the current branch with the actual files these git lfs
# placeholders point to.
git lfs checkout
Run Code Online (Sandbox Code Playgroud)

git lfs有关上面显示的命令的详细信息,请参阅我的另一个答案:如何作为基本用户使用: 、、和git lfs之间有什么区别git lfs fetchgit lfs fetch --allgit lfs pullgit lfs checkout

细节

首先,您需要知道 .git 文件夹中的哪些内容占用了这么多空间。ncdu一种技术是在存储库中运行基于 ncurses(类似 GUI) (NCurses 磁盘使用)的命令。另一种方法是运行它:

du -h --max-depth=1 .git
Run Code Online (Sandbox Code Playgroud)

旁注:要查看您的存储库有多大(不包括您的.git文件夹),请运行以下命令:

du -h --max-depth=1 --exclude=.git .
Run Code Online (Sandbox Code Playgroud)

上面第一个命令的示例输出:

$ du -h --max-depth=1 .git
158G    .git/lfs
6.2M    .git/refs
4.0K    .git/branches
2.5M    .git/info
3.7G    .git/objects
6.2M    .git/logs
68K .git/hooks
162G    .git
Run Code Online (Sandbox Code Playgroud)

如您所见,我的.git文件夹总大小为162 GB,但其中158 GB.git/lfs是我的文件夹,因为我使用第 3 方“ Git Large File Storage”( git lfs)工具来存储大型二进制文件。因此,运行此命令可以显着减少。注意:time以下所有命令的部分是可选的:

time git lfs prune
Run Code Online (Sandbox Code Playgroud)

(如果git lfs prune失败并出现“恐慌:运行时错误:无效的内存地址或零指针取消引用”,请参阅下面的注释。)

来源:如何收缩 git LFS repo
官方文档:git-lfs-prune(1)--从本地存储中删除旧的 LFS 文件

跑了60秒!

现在我刚刚释放了62 GB!我的.git/lfs文件夹现在只有96 GB,如下所示:

$ du -h --max-depth=1 .git
96G .git/lfs
6.2M    .git/refs
4.0K    .git/branches
2.5M    .git/info
3.0G    .git/objects
6.2M    .git/logs
68K .git/hooks
99G .git
Run Code Online (Sandbox Code Playgroud)

接下来,运行此命令将.git/objects文件夹缩小几百 MB 至约 1 GB 左右:

time git gc
time git prune
Run Code Online (Sandbox Code Playgroud)

git gc运行时间约3分钟,git prune运行时间约1分钟。

使用 再次检查您的磁盘使用情况du -h --max-depth=1 .git。如果您想节省更多空间,请运行以下命令:

time git repack -a -d --depth=250 --window=250
Run Code Online (Sandbox Code Playgroud)

这大约需要 2 分钟,并且可以节省数百 MB 的空间。

现在,您可以停在这里,或者您可以运行最后的命令:

time git gc --aggressive --prune
Run Code Online (Sandbox Code Playgroud)

最终命令将节省数百MB,但需要大约 1.25 小时。

如果git lfs prune失败并显示“紧急:运行时错误:无效的内存地址或零指针取消引用”

如果git lfs prune失败:

恐慌:运行时错误:无效的内存地址或零指针取消引用

那么您可能安装了旧版本git-lfs并需要更新它。具体方法如下:

首先,检查您安装的版本。运行man git-lfs并滚动到底部以查看日期。例如,它可能说是 2017 年的。现在,使用这些命令更新您的版本。第一个命令来自这里: https: //packagecloud.io/github/git-lfs/install

curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt update
sudo apt install git-lfs
Run Code Online (Sandbox Code Playgroud)

再次运行man git-lfs并滚动到底部。我现在看到的日期是“2021 年 3 月”,而之前是 2017 年的某个日期。

另外,如果我sudo apt install git-lfs再次运行,它会告诉我:

git-lfs 已经是最新版本(2.13.3)。

所以,更新有效git-lfs,现在错误消失了git lfs prune再次工作!

我首先在 GitHub 上的评论中记录了这一点: https: //github.com/git-lfs/git-lfs/issues/3395#issuecomment-889393444

参考:

  1. @knittl:如何缩小 .git 文件夹
  2. @David Dehghan:如何缩小 .git 文件夹
  3. git lfs prune:如何缩小 git LFS 存储库
  4. 莱纳斯·托瓦尔兹git repack -a -d --depth=250 --window=250: https: //gcc.gnu.org/legacy-ml/gcc/2007-12/msg00165.html
  5. https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-prune.1.ronn

也可以看看:

  1. git 会消除文件之间的重复吗?
  2. 我的问答:git LFS 如何比 git 更高效地跟踪和存储二进制数据?
  3. 我的答案: Unix & Linux:关于根据文件大小查找、过滤和排序的所有内容find- 请参阅末尾附近的示例,标题为“(找出要添加到git lfs下一个的文件扩展名)”
  4. 其他真正有用的 git lfs信息:
    1. 很棒的文章!:我的开发者星球:Git LFS:为什么以及如何使用
    2. https://git-lfs.github.com/
    3. 我的仓库和注释:https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles#how-to-clone-this-repo-and-all-git-submodules
    4. ***** [我的问答]基础用户如何使用: 、、、 和git lfs之间有什么区别?git lfs fetchgit lfs fetch --allgit lfs pullgit lfs checkout
  5. [我的问答]如何在 `git checkout` 失败后恢复 `git lfs post-checkout` 钩子
  6. 注意:对于纯粹的同步,请尝试 FreeFileSync 或rsync正如我在此处的回答中所解释的那样。话虽如此,我偶尔也会使用git同步,正如我在这里解释我的sync_git_repo_from_pc1_to_pc2.sh工具以及我的其他答案:通过 SSH 使用 Eclipse 处理远程项目
  7. ***** 我的答案: Git 中的文件限制是多少(数量和大小)?
  8. ***** 我的回答:git 会消除文件之间的重复吗?


Let*_*_Be 8

5GB对200MB有点奇怪.试着跑git gc.

但是,除非您将存储库拆分为模块,否则无法减小.git目录的大小.

git repo的每个克隆都是一个完整的存储库,可以充当服务器.这是分布式版本控制的基本原则.


Yas*_*ash 8

.git通过根据上次更新时间从文件夹中删除一些文件日志历史记录来缩小 Git 存储库。

我在本地计算机上遇到了同样的问题。原因是我从本地删除了一些大量文件并提交到中央存储库。但事件发生后git statusgit fetchgit pull。我的.git文件夹大小约为 3GB。.git后来我运行以下命令,通过考虑一个月前已更改/过期的文件来减小文件夹的大小。

命令

$ git remote prune origin && git repack && git prune-packed && git reflog expire --expire=1.month.ago && git gc --aggressive
Run Code Online (Sandbox Code Playgroud)

Git命令及其简短描述:

  • git-prune- 从对象数据库中删除所有无法访问的对象
  • git-repack- 将解压的对象打包到存储库中
  • git-prune-packed- 删除包文件中已有的额外对象。
  • git reflog:Git 使用称为引用日志或“reflogs”的机制来跟踪分支尖端的更新。Reflogs 跟踪本地存储库中 Git 引用的更新时间。除了分支提示引用日志之外,还为 Git 存储维护一个特殊的引用日志。引用日志存储在本地存储库.git目录下的目录中。.git/logs/refs/heads/.git reflog 目录可以在、找到,如果 git stash 已在存储库上使用,.git/logs/HEAD也可以在 、 找到。.git/logs/refs/stashgit reflog 在页面上处于较高级别Rewriting History
    git reflog expire --expire=now --expire-unreachable=now --all
    除了在引用日志中保留历史记录之外,Git 还规定了删除分离提交的内部到期日期。同样,这些都是git gc处理的实现细节,git prune不应该单独使用。
  • git gc --aggressive: git-gc - 清理不必要的文件并优化本地存储库。
    在幕后 git gc 实际上执行了一系列其他内部子命令,例如git prune, git repack, git pack and git rerere. 这些命令的高级职责是识别超出配置设置的阈值级别的任何 Git 对象git gc。一旦识别出来,这些对象就会被压缩或相应地修剪。

Commonad 的结果:

$ git remote prune origin && git repack && git prune-packed && git reflog expire --expire=1.month.ago && git gc --aggressive
Enumerating objects: 535, done.
Counting objects: 100% (340/340), done.
Delta compression using up to 2 threads
Compressing objects: 100% (263/263), done.
Writing objects: 100% (340/340), done.
Total 340 (delta 104), reused 0 (delta 0)
Enumerating objects: 904, done.
Counting objects: 100% (904/904), done.
Delta compression using up to 2 threads
Compressing objects: 100% (771/771), done.
Writing objects: 100% (904/904), done.
Total 904 (delta 343), reused 561 (delta 0)
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

52561 次

最近记录:

6 年,1 月 前