Article

文件已经 commit 但还没 push 时,如何把大文件或目录从 Git 历史和跟踪中移除。

2026/7/5#git#教程#仓库管理

Q:有个文件和文件夹已经git commit了 但是没有push 现在想把这个文件夹单独剔除,不跟踪 因为太大了 不成传到github 应该怎么做

如果已经 commit,但还没 push,这是最好处理的时候。

假设目录结构:

project/
├── src/
├── docs/
├── models/       ← 这个文件夹太大
└── .gitignore

你已经:

git add .
git commit -m "initial commit"

现在发现:

models/

不应该上传 GitHub。


方法1(推荐):从 Git 历史中移除该目录

第一步:加入 .gitignore

编辑:

vim .gitignore

添加:

models/

第二步:取消 Git 跟踪

注意:

git rm -r --cached models

这里非常重要:

--cached

表示:

只从Git索引删除
不删除硬盘文件

执行后:

git status

会看到:

deleted: models/xxx.bin
deleted: models/yyy.pt

实际上文件还在硬盘里。


第三步:重新提交

git commit -m "remove models from tracking"

这样以后:

git push

GitHub 不会收到这个目录。


但是有个问题

如果:

models/
有10GB

虽然没 push,

但它已经存在于本地 Git 历史。

执行:

git log

还能找到。

Git 仓库体积仍然巨大。


方法2(更干净)

如果最近一次 commit 就是那个错误提交:

例如:

git log --oneline
abc123 initial commit

只有这一条。

那么直接:

git reset --soft HEAD~1

或者如果只有一个提交:

git reset HEAD~1

然后:

echo "models/" >> .gitignore
git add .
git commit -m "initial commit"

重新提交一次。

这样:

models
从未进入Git历史

最干净。


方法3(已经有很多 commit)

例如:

A
B
C
D ← 当前

models 在 A 中就提交了。

虽然没 push,但后面已经开发很多。

此时推荐:

git filter-repo

彻底删除历史。

安装:

brew install git-filter-repo

执行:

git filter-repo --path models --invert-paths

意思:

把整个Git历史中的models目录全部删除

然后:

git push --force

(你现在还没 push,其实不需要 force)


你现在最可能属于哪种情况?

执行:

git log --oneline --graph

如果结果类似:

* a1b2c3 initial commit

只有一个 commit。

直接:

git reset --soft HEAD~1
echo "models/" >> .gitignore
git add .
git commit -m "initial commit"

这是最干净的方案。

如果你把下面两条命令结果发出来:

git log --oneline --graph --all -10
du -sh .git

我可以告诉你应该用 git rm --cachedgit reset 还是 git filter-repo