How to clean up accidentally committed large files in git history?
The author, while updating their video editing tool Clipify, encountered an issue where numerous static resource files in the Git repository slowed down the push speed. After analysis, they found that using the `git rm --cached` command couldn't fully resolve the problem, as Git still retained large files in the historical commits. The author ultimately used the git-filter-repo tool to rewrite the Git commit history, successfully addressing the slow push issue, and also introduced how to use the git-sizer tool to analyze large files in Git repositories.
目录9 个章节
Preface
Hello! Long time no see~
I've been thinking about a career transition recently and haven't updated my articles for a while.
But seeing that the video editing tool Clipify I developed earlier has gained many stars reminded me that the promises I made before have only been partially realized. So, I used my spare time over the weekend to refactor the Clipify project's interface and develop some new features.
During this process, I realized that the current tech stack of WinForms + Blazor is like strapping a rocket to a carriage—giving off a steampunk retro vibe. Although the interface developed with front-end technologies looks great, WinForms' inability to be cross-platform isn't a long-term solution.
So, I started trying to migrate to MAUI. Although it still doesn't support Linux, at least it works on Mac, which counts as being cross-platform, I guess…
However, before I could even get the project running, I accidentally committed a bunch of static resources:
Clipify.Maui/wwwroot/lib/
Clipify.Maui/wwwroot/css/*.min.css
Clipify.Maui/wwwroot/temp/
This made git push super slow and would consume a lot of storage space.
Fortunately, with the help of the AI assistant, I managed to resolve this issue.
But I thought I can't keep bothering the AI assistant all the time. Since the problem was solved, I should document it so that I can handle similar situations more easily in the future.
Using Git Native Commands
This is actually a well-known issue
Many articles you can find online will tell you that you can solve it using the following commands
git rm -r --cached Clipify.Maui/wwwroot/lib
git rm --cached Clipify.Maui/wwwroot/css/*.min.css
git rm -r --cached Clipify.Maui/wwwroot/temp
These commands will remove the committed files, but will not delete local files
But even after I did this, it still didn't work, and git push remained very slow
Analysis of the Cause
So the question is, why doesn't git rm --cached work?
The reason is that git rm --cached only removes the Git tracking of the specified file from the current commit (working directory); it does not modify the past commit history.
It solves the problem of "stop tracking from now on," but for files it has tracked historically, Git will still keep them in the object database (.git/objects).
In the previous few commits, I already committed folders like Clipify.Maui/wwwroot/lib.
So, for this scenario, this command is useless. 😂
In simple terms, Git is a version control tool; it does not forget your historical commits. Even if you remove the lib/ folder now with git rm --cached, Git still remembers that it was included in the Nth commit before. Therefore, the .git directory still holds those large blob files, and they will still need to be transferred during a push.
Solution
So how do we solve this?
The method I saw before was writing a script to loop through and delete committed files from each commit.
Now, it's no longer that troublesome, thanks to the git-filter-repo tool, a Python tool used to rewrite Git history.
https://github.com/newren/git-filter-repo
Thanks to scoop, which allows me to get a similar software installation experience on Windows as on Linux/MacOS.
# Install Git Filter Repo
brew install git-filter-repo # macOS
scoop install git-filter-repo # Windows
# Or install with Python
pip install git-filter-repo
Usage
git filter-repo --path Clipify.Maui/wwwroot/lib/ --invert-paths --force
This command will completely delete all files and commit records related to this path from history
After rewriting the entire Git commit history, the repository size will be significantly reduced, git push will be faster, and the specified files in historical commits will be completely removed. You may need to use --force to force push the code.
After going through this process, using git push to submit was noticeably much faster for me.
Extension: Batch Deletion
The git filter-repo --path parameter specifies a single path and does not support wildcards.
git filter-repo actually has a hidden feature: supports --path-glob (glob wildcard pattern), which is more flexible than --path.
For example, to delete all .png files under public/image-grid:
git filter-repo --path-glob 'public/image-grid/*.png' --invert-paths --force
You can also delete recursively in subdirectories:
git filter-repo --path-glob 'public/image-grid/**/*.png' --invert-paths --force
Extension: How to analyze large files in git commit history
Using [git rev-list + git verify-pack] can find large objects (large files) in Git commit history.
However, the native git commands are quite complex.
I still choose to rely on the power of tools, this time the git-sizer tool.
git-sizer is an official tool from GitHub, used to analyze issues like Git repository size, commit volume, etc.
brew install git-sizer
or
scoop install git-sizer
Install via cargo
cargo install git-sizer
PS:Thanks again to scoop!
Execute git-sizer directly in the project root directory.
This tool will output the following information:
- Largest commits
- Largest blobs (file content)
- Largest directories
- Branches containing large files
- Whether there are hidden bloated objects in history (hidden bloats)
The result I obtained using this tool looks like this:
Processing blobs: 2448
Processing trees: 218
Processing commits: 42
Matching commits to trees: 42
Processing annotated tags: 0
Processing references: 3
| Name | Value | Level of concern |
| ---------------------------- | --------- | ------------------------------ |
| Biggest objects | | |
| * Trees | | |
| * Maximum entries [1] | 1.40 k | * |
[1] 77b7ff2aa0456193bee83eebe9dfb76ebd4f35ac (2d9cc135f1aff0863ce2ef8ceff3cbf6984ee499:Clipify.Maui/wwwroot/lib/font-awesome/svgs/solid)
This way, you can easily locate the largest files and slim down your git repository 🎉
Extension: Finding the Large File List
At first, I was thinking of using git commands combined with pipes.
But that was too much hassle.
In the end, git-filter-repo is amazing!!
One command solves it all.
git filter-repo --analyze
After running, a .git/filter-repo/ folder will be generated in the repository directory.
Inside, you will find:
analysis/blob-shas-and-paths.txt- A file list with size statistics.analysis/directories-all-sizes.txt- A directory list with size statistics.
There are other files too; if you're interested, you can explore them yourself. I mainly focused on these two files.
_EOF_
How to clean up accidentally committed large files in git history?
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
从Git-repository中移除文件
使用 git rm --cached -r 命令,从版本库中移除 git rm -r --cached *.iml output rm 'commons/commons.iml' rm 'estate-repo.iml' rm 'service/service.iml' 然后重新提交
2023-03-20 · Git · 约 1 分钟
导出Git提交记录
https://git-scm.com/docs/git-log#Documentation/git-log.txt-emnem git log export command git log --after=2021-1-1 --before=2022-1-1 --pretty=format:'%cs,%an,%s' output 2021-12-17,DealiAxy,swagger文档优化 2
2023-03-20 · Git · 约 1 分钟
模型文件硬塞进 Git,GitHub 直接打回原形:使用Git-LFS管理大文件
GitHub硬怼大文件?Git LFS了解一下,免费额度逼得你快用完就买。别指望这玩意儿当网盘用,模型放代码里提交是吧?这操作真是下饭。
2025-08-27 · Git · 约 1 分钟
Git command returns fatal error about the repository being owned by someone else
https://confluence.atlassian.com/bbkb/git-command-returns-fatal-error-about-the-repository-being-owned-by-someone-else-1167744132.html Summary When trying to execute a git command in a repository, suc
2023-03-20 · Git · 约 1 分钟
讨论
共 0 条加载评论中…