有没有办法减小git文件夹的大小?

179

看起来我的项目每次 commit/push 都越来越大了。有没有一种方法可以清理我的git文件夹?


7个回答

235

我不确定您想要什么。首先,每次提交/推送时,由于必须存储每个附加提交,因此目录的大小肯定会稍微增加。

但是,您可能需要使用git gc命令,它将“清理不必要的文件并优化本地存储库”(手册页面)。

另一个可能相关的命令是git clean,它将从您的树中删除未跟踪的文件(手册页面)。


31
git clean -d -f -x命令会删除在.gitignore中列出的文件等。例如不应被纳入git的工作区,Pods文件夹等。 - Kalle
124
警告:@Kalle 所写的上述命令将会删除你 Git 根目录下的 所有未跟踪文件和目录 ,不只是“列在 .gitignore 文件中的文件”。无论一个文件是否被列在 .gitignore 中,只要它没有被 Git 跟踪,都将被清除。git clean -dfX(注意大写的 X)只会删除在 .gitignore 中有对应规则的项目。请注意这个警告:永远不要在不使用交互模式 -i 或至少进行干预运行 -n 的情况下执行 git clean 命令。 - Adrian Günter
6
或者进行备份 :-) - Mateen Ulhaq
制作备份 - Lee Goddard

75

运行:

git remote prune origin

删除所有已在origin中被删除但仍然在remotes/origin本地可用的过期跟踪分支。

git gc --auto

'垃圾回收' - 运行清理任务(压缩修订版本,删除松散/无法访问的对象)。--auto 标志首先确定是否需要任何工作,如果不需要,则退出而不执行任何操作。

5
这些是做什么的?我知道我们可以通过Google搜索它们并查找它们的文档,但是当涉及到代码或命令时,提供简短的描述是一种常见做法。 - Dzhuneyt

28

在一些情况下,每次提交后你的git仓库会变得越来越大,比如你需要定期生成二进制文件并将其提交到仓库中 (与文本文件相比,存储效率较低)

另一个情况是,如果你在同一个仓库中有大量文件(这是git的限制),而不是使用多个子仓库(作为子模块进行管理)。

在这篇讲解git空间的文章中,AlBlue提到:

请注意,Git(和Hg等其他分布式版本控制系统)存在这样一个问题,即如果检入了(大型)二进制文件,然后将其删除,即使它们已经不再存在,它们仍会出现在仓库中,并占用空间。

如果你的git仓库中有大型二进制文件,建议你:

  • 尝试使用 git filter-branch 从历史记录中删除那些二进制文件(警告:这将重写历史记录,如果您已经推送了您的repo并且其他人已经从中拉取,则会产生问题)
  • 如我在 "Git 中有哪些文件限制(数量和大小)?"中提到的那样,最近的GitHub Git LFS(2015年发布,比这个答案晚了5年)是一种管理大文件的方法(通过将它们存储在 Git 仓库之外)。


    1
    如果您经常添加/更新大型二进制文件(如图像),则Git大文件支持非常有用。请参阅https://git-lfs.github.com/。它非常容易实现,并受GitHub支持。所有团队成员都需要安装它,以便能够进行协作使用。 - Eric Woods
    哈,确实!有趣的是,一个九年多前的答案仍然很相关(现在甚至更加如此,因为有了LFS信息)。 - Eric Woods

    28

    是的,git gc 是解决方案,当然了,

    而且在本地 - 你可以直接删除本地仓库并重新克隆它,

    但这里有更重要的事情...

    你等待那个巨大的 git & externals 处理的几秒钟会积累成长时间的几分钟,进而积累成浪费的几小时,效率低下。

    从头开始创建一个新的 (完全的,不只是一个分支) 仓库,包括最近版本的文件,当然你会失去所有历史记录,

    但在代码世界中,现在不是感伤的时候,每次提交或差异都带着整整5年的代码是没有意义的, 如果你想怀旧,你仍然可以把旧的 git & externals 存储在某个地方 :]

    但是,你真的必须向前迈进 :]

    你的团队会感谢你!


    16
    完全同意,最近我们对一个旧代码库采取了这种做法,从此不再回头;主要也是因为我们无法回头,但你知道我的意思 :) - WhatIsHeDoing

    20
    运行这个命令非常危险,但是会通过删除所有的git恢复/备份文件来缩小您的代码库:
    运行此命令十分危险,会删除所有的git恢复/备份文件,但可通过此方式缩减您的代码库。
    git reflog expire --expire=now --all && git gc --prune=now --aggressive
    

    它将删除git用于从某些错误命令中恢复存储库的所有文件,例如,如果您执行了git reset --hard,通常可以恢复丢失的文件。但是,如果您在执行git reflog expire...命令之前执行git reset --hard,那么您将失去所有东西。现在,您唯一的希望是使用一些工具来分析您的文件系统,并尝试恢复被删除的文件(如果它们没有被覆盖)。


    4
    我不认为这是“极其危险”的,我只会说这是需要小心的事情。以我的经验,很少有人会接触reflog或不可达对象——大多数人甚至都不知道它们存在或如何与它们交互,因此会陷入需要它们帮助或者使用低效方法的境地。我敢说,如果你不知道这些命令会做什么,也无法弄清楚,那么你可以放心地运行它们! - Chris Morgan

    12

    git clean -d -f -i 是最好的方法。

    这将帮助以更加受控的方式进行清理。

    -i 代表交互模式。


    5
    尽管提问者的问题不够清晰,但这个回答在这方面很好。我想指出的是,git clean 不是为了清理存储库,而是为了清理目录。对于盲目复制/粘贴的用户,请注意:它会删除您可能希望在本地保留的未跟踪文件/目录。 - sraboy
    如果你想要进行深度清理,git clean -d -x -f非常好用。 - Rishabh Jain

    1

    我不确定它是否会收缩它,但是在运行git clean之后,我经常执行git repack -ad,这可以减少打包文件的数量。


    6
    repackgit gc 过程的一部分,因此无需单独运行。 - artkoshelev

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接