一、问题现象
执行 git pull 时报错:
|
1
2
3
4
5
|
error: Your local changes to the following files would be overwritten by merge:
backend/app/api/v1/__pycache__/__init__.cpython-311.pyc
backend/app/core/__pycache__/config.cpython-311.pyc
Please commit your changes or stash them before you merge.
Aborting
|
明明已在 .gitignore 中配置了 __pycache__/,但 Git 仍然报错。
二、原因分析
1..gitignore只对未跟踪文件生效
.gitignore 的作用是告诉 Git 忽略特定文件的版本跟踪。但如果文件已经被 git add 提交到仓库,.gitignore 对它无效。
|
1
2
3
4
|
文件生命周期:
[未被跟踪] → git add → [已被跟踪] → .gitignore无法忽略
↑
悲剧发生的地方
|
2. 典型成因
| 场景 |
说明 |
| 首次 git init 后直接运行 Python |
此时 pycache 已生成,可能被一起 add |
| 从其他分支合并代码 |
被跟踪的 pycache 跟着一起合并过来 |
| 项目初期未配置 .gitignore |
后期添加后,历史提交中的 pycache 仍在跟踪 |
三、解决方案
步骤 1:确认 pycache 是否被跟踪
|
1
2
|
# 检查文件是否在 git 索引中
git ls-files --error-unmatch backend/app/__pycache__/xxx.cpython-311.pyc
|
步骤 2:从 Git 索引移除(保留本地文件)
|
1
2
3
4
5
6
7
8
|
# 移除单个目录
git rm --cached -r backend/app/__pycache__
# 移除所有 pycache 目录
git rm --cached -r backend/app/__pycache__ \
backend/app/api/__pycache__ \
backend/app/core/__pycache__ \
backend/app/services/__pycache__
|
步骤 3:提交更改
|
1
|
git commit -m "chore: remove __pycache__ from git index"
|
步骤 4:后续 .gitignore 生效
此后新建的 __pycache__ 目录会自动被忽略。
四、预防措施
1. 项目初始化时配置 .gitignore
|
1
2
3
|
# 创建项目时先生成 .gitignore,再 git init
echo "__pycache__/" >> .gitignore
git init
|
2. 全局 Gitignore(推荐)
|
1
2
3
|
# 创建全局忽略规则(所有项目生效)
git config --global core.excludesFile ~/.gitignore
echo "__pycache__/" >> ~/.gitignore
|
3. IDE 配置
| IDE |
配置方式 |
| VS Code |
设置 "files.exclude" 添加 **/__pycache__" |
| PyCharm |
Settings → Project → Project Structure 添加 __pycache__ |
4. Docker/虚拟环境隔离
|
1
2
3
4
|
# Dockerfile 中确保容器内不包含宿主的 pycache
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
|
五、验证 .gitignore 是否生效
|
1
2
3
4
5
6
|
# 方法 1:查看 git status,pycache 不应出现
git status
# 方法 2:查看 git check-ignore
git check-ignore -v backend/app/__pycache__/xxx.pyc
# 输出非空表示被忽略
|
六、常见误区
| 误区 |
真相 |
| 添加 .gitignore 后文件自动忽略 |
必须先 git rm --cached 移除已跟踪文件 |
| .gitignore 可以忽略历史提交中的文件 |
需要 git filter-branch 或 BFG 清理历史 |
| __pycache__ 只在 Python 3.7+ 存在 |
Python 2 的 *.pyc 同样需要忽略 |
七、一键修复脚本
|
1
2
3
4
5
6
7
8
|
#!/bin/bash
# remove_pycache.sh
# 查找所有被跟踪的 __pycache__ 目录
git ls-files | grep -E '__pycache__|\.pyc$' | xargs -I {} git rm --cached {}
echo "已移除所有 pycache 跟踪"
echo "本地文件未删除,仅停止版本控制"
|
八、总结
|
1
2
3
4
5
6
7
|
┌─────────────────────────────────────────────────────────┐
│ .gitignore 只对未跟踪文件生效 │
│ │
│ 已跟踪 → .gitignore 无效 → 必须 git rm --cached │
│ │
│ 预防 > 治疗:项目初始化时配置全局忽略规则 │
└─────────────────────────────────────────────────────────┘
|
核心原则:.gitignore 是"从此以后忽略",不是"从此之前忽略"。
|