文章

如何清理 .git 文件夹来减小 github 仓库大小

本文介绍了如何在


1. github

1.1. git 命令

1.2. github 桌面

1.3. .git 文件夹

2. .git 文件夹清理

需要 Linux 环境。

  • 检查仓库是否存在未提交的更改

    如果仓库存在未提交的更改,会在后续操作中提示提示 Cannot rewrite branches: You have unstaged changes. 表明尝试重写分支时,有一些未暂存的更改。这意味着你在Git版本控制中,工作目录或者暂存区有一些更改还没有被添加到暂存区。因此,Git不能进行重写操作,因为这可能会导致你丢失这些未提交的更改。

    可以通过以下命令检查本地仓库与云端仓库的差异,定位未提交的更改

    1
    
      git diff
    

    执行命令后按 q 退出。

    可以通过以下命令提交更改

    1
    2
    
      git add . # 将所有文件添加到暂存区
      git commit -m "Your commit message" # 提交你的更改
    

    或丢弃更改

    1
    
      git checkout -- . # 丢弃工作目录中的所有更改
    
  • 查看占用仓库大小最大的文件

    bash 下执行以下命令

    1
    
      git rev-list --objects --all | grep -f <(git verify-pack -v .git/objects/pack/*.idx| sort -k 3 -n | cut -f 1 -d " " | tail -N)
    

    举例

    1
    
      git rev-list --objects --all | grep -f <(git verify-pack -v .git/objects/pack/pack-3a121311b111a111c11111x1111f111111111111.idx| sort -k 3 -n | cut -f 1 -d " " | tail -10)
    

    将在控制台输出类似如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      344ee5dcae1xxxxx3d80daa8714ed7d16b21dxxx src/vehicles/cls_Spacecraft.cpp
      98eecfdf58a0c0dc33bbfae46bxxxe5d837d5xxx src/vehicles/cls_Spacecraft_Docker.cpp
      a8a5bca95b08084xxxx7160c4c5d98631f1cdxxx config/usrSpacecraft.json
      e1cf4bf431f82d788fcaaaaac4ecca05503248xxx winDSSimulator.exe
      8932ce1bca5ba3c1ae39cxxxx054d14f15ad8xxx winDSSimulator.exe
      17965fde8b22564a73addxxx10e77a815ef89xxx src/SimDynamics.cpp
      33e7714xxxxaa033326648609f614837f49d2xxx winDSSimulator.exe
      f3c41a010b75743fbb111161d84ebcc57ae85xxx winDSSimulator.exe
      058da4754e97e910a72xxxxxxxa4d6f6513f5xxx winDSSimulator.exe
      351e85631xxxx609d92523a67ca5d1e3e7f47xxx src/class/clsEarthDynamics.cpp
    
  • 从历史中移除大文件

    使用以下命令检查仓库中的文件个数(在执行 filter-branch 清理命令后个数会减少)

    1
    
      git count-objects -v
    

    对于每次提交操作,filter-branch 命令都会使用给定的过滤器重写仓库的历史。

    以下命令删除历史中存在的图像(例如 *.exe*.json*.jpg*.png*.gif),这些文件类型是常见的无需跟踪和回退修改的文件。

    1
    
      git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch "config/**.json" "**.exe" "**.jpg" "**.png" "**.gif"' --prune-empty --tag-name-filter cat -- --all
    

    需要注意以下几点:

    • git rm --cached:这个命令会从Git的索引中移除指定的文件,而不是从工作目录中移除。这意味着你的工作目录中仍然会保留这些文件的副本。如果你希望从工作目录和索引中都删除这些文件,你应该使用git rm –cached -r –ignore-unmatch…这样的命令。
    • 文件模式:你使用的文件模式,例如 "config/**.jpg""**.png" 等,是用双引号包围的。这通常是可以正常工作的,但是如果你在文件名中有一些特殊字符或者空格,可能会导致问题。你需要确定这些模式正确匹配了你想要删除的文件。
    • --prune-empty:这个选项会导致Git丢弃那些没有任何修改的提交。因为你的操作可能导致一些提交没有任何修改,所以这个选项可能会被用到。
    • --tag-name-filter cat:这个选项会重命名所有的标签。cat命令会直接输出标签名,这意味着你的标签名字可能会改变。你需要考虑这是否是你想要的行为。
    • --all:这个选项会让Git处理所有的引用,包括所有分支和标签。如果你只想处理特定的分支或标签,你可以去掉这个选项。
  • 清理仓库

    清楚旧提交中不需要的日志和文件。

    1
    2
    3
    
      rm -Rf .git/refs/original
      rm -Rf .git/logs/
      git gc --aggressive --prune=now
    

    将清理后的本地仓库更新到云端。

    1
    2
    
      git push origin --force --all
      git push origin --force --tags
    

3. 参考文献

[1] Junyong Lee. How to clean up .git folder for reducing repository size

本文由作者按照 CC BY 4.0 进行授权