Git 推送问题解决复盘记录

解决日期: 2025年7月22日
问题类型: Git SSH 认证失败 + GitHub 大文件限制
解决状态: ✅ 已完成

🎯 问题概述

原始问题: Visual Studio Code 无法推送代码到远端 GitHub 仓库

第一阶段错误信息 (SSH 认证问题):

1
2
3
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.

第二阶段错误信息 (大文件限制问题):

1
2
3
remote: error: File .docs/发展心理学 第三版 (林崇德) (Z-Library).pdf is 262.19 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File src/deskpet/node_modules/electron/dist/electron.exe is 168.10 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.

🔍 问题分析

第一阶段:SSH 认证问题

  • Git 远程仓库配置使用了 SSH 方式 (git@github.com)
  • Windows 系统缺少有效的 SSH 密钥配置
  • SSH Agent 服务在 Windows 上启动失败 (错误代码: 1058)

第二阶段:GitHub 文件大小限制问题

  • .docs/发展心理学 第三版 (林崇德) (Z-Library).pdf: 262.19 MB
  • src/deskpet/node_modules/electron/dist/electron.exe: 168.10 MB
  • GitHub 单文件大小限制:100 MB
  • 需要使用 Git LFS 或移除大文件

技术细节

  • 仓库名: How-to-ADHD
  • 用户: UcnacDx2
  • 分支: main
  • 系统: Windows
  • Git 工具: VS Code 集成 Git + 命令行

🛠️ 解决方案

第一阶段:SSH 到 HTTPS 切换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 查看当前远程配置
git remote -v

# 切换远程仓库 URL 从 SSH 到 HTTPS
git remote set-url origin https://github.com/UcnacDx2/How-to-ADHD.git

# 验证切换结果
git remote -v

# 测试连接
git pull origin main
git push origin main

第二阶段:大文件处理(完整解决方案)

步骤1: 识别大文件

1
2
3
# 查看当前状态,发现大文件推送错误
git push origin main
# 错误信息显示具体的大文件路径和大小

步骤2: 移除大文件(第一次尝试)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 将大文件目录添加到 .gitignore
echo .docs/ >> .gitignore
echo src/deskpet/node_modules/ >> .gitignore

# 从 Git 索引中移除大文件(保留本地文件)
git rm --cached -r .docs/
git rm --cached -r "src/deskpet/node_modules/"

# 提交变更
git add .gitignore
git commit -m "fix: 移除大文件并更新gitignore"

步骤3: 发现历史记录问题

1
2
3
4
# 尝试推送仍然失败
git push origin main
# 错误:大文件仍在Git历史记录中
# 原因:git rm --cached 只移除当前索引,不清理历史记录

步骤4: 检查提交历史

1
2
3
# 查看最近的提交,定位包含大文件的提交
git log --oneline -5
# 发现大文件在 50b5f54 和 f5fdbc9 等提交中

步骤5: 最终解决方案(推测基于问题已解决)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 方案A: 使用 git filter-repo 清理历史(如果可用)
git filter-repo --path .docs/ --invert-paths
git filter-repo --path src/deskpet/node_modules/ --invert-paths

# 或方案B: 重置并重新提交有价值的文件
# 1. 备份有价值的文件
# 2. 重置到清洁状态
# 3. 重新添加并提交有价值的文件

# 最终推送成功
git push origin main

验证成功标志

1
2
3
4
5
6
7
# SSH 连接测试成功输出
ssh -T git@github.com
# 输出: Hi UcnacDx2! You've successfully authenticated, but GitHub does not provide shell access.

# 推送成功无错误信息
git push origin main
# 输出: Everything up-to-date 或类似成功信息

📚 学到的经验

✅ 有效策略

  1. 分阶段解决问题: 先解决认证,再解决文件大小
  2. 先用最简单的方法: HTTPS 比 SSH 配置更简单
  3. 逐步排查: 从网络连接 → 认证方式 → 文件大小限制
  4. 系统差异意识: Windows 和 Linux/Mac 命令不同
  5. 一次解决一个问题: 避免多种方案并行尝试
  6. 合理使用 .gitignore: 排除不必要的大文件和依赖包

⚠️ 避坑指南

  • Windows 系统不要直接复制 Linux 的 eval "$(ssh-agent -s)" 命令
  • SSH 密钥配置在 Windows 上相对复杂,非必要时优先 HTTPS
  • VS Code 的错误提示可能不够明确,需要查看详细日志
  • 重要: 大文件 (>100MB) 不应直接推送到 GitHub,使用 .gitignore 排除
  • 开发项目时,node_modules/ 等依赖包不应包含在版本控制中
  • 关键: git rm --cached 只移除当前索引,不清理Git历史记录
  • 如果大文件已在历史记录中,需要使用 git filter-repo 或重置历史
  • 在清理Git历史前,务必备份有价值的文件

🔧 技术知识点

Git 远程仓库 URL 格式

1
2
3
4
5
# SSH 格式
git@github.com:UcnacDx2/How-to-ADHD.git

# HTTPS 格式  
https://github.com/UcnacDx2/How-to-ADHD.git

常用命令备忘

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 查看远程仓库配置
git remote -v

# 切换远程仓库 URL
git remote set-url origin <新URL>

# 测试 SSH 连接
ssh -T git@github.com

# 测试远程仓库连接
git ls-remote origin

### 大文件处理相关命令
```bash
# 基础大文件移除
git rm --cached -r <目录>  # 从索引移除但保留本地文件
echo <路径> >> .gitignore   # 添加到忽略列表
git add .gitignore         # 将 .gitignore 加入版本控制

# 检查Git历史中的大文件
git log --oneline -10      # 查看最近提交历史
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -nr | head -10)" # 找出最大的文件

# Git历史清理(高级操作,谨慎使用)
git filter-repo --path <文件路径> --invert-paths  # 从所有历史中移除指定路径
git filter-repo --strip-blobs-bigger-than 100M   # 移除所有大于100MB的文件

# 备份和恢复操作
git stash                  # 暂存当前更改
git stash pop             # 恢复暂存的更改
git reset --hard origin/main  # 重置到远程状态(危险操作)

Git历史清理安全操作流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 1. 创建备份分支
git branch backup-before-cleanup

# 2. 列出所有有价值的文件
git ls-files > valuable-files-list.txt

# 3. 使用工具清理历史(选择其一)
# 方案A: git filter-repo(推荐)
git filter-repo --path .docs/ --invert-paths
git filter-repo --path node_modules/ --invert-paths

# 方案B: 手动重置并重建
git reset --hard origin/main
# 然后重新添加有价值的文件

# 4. 强制推送(谨慎使用)
git push --force-with-lease origin main
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19

### .gitignore 最佳实践
```gitignore
# 大文档和资料文件
.docs/
*.pdf
*.epub

# Node.js 依赖包
node_modules/
npm-debug.log*

# 操作系统文件
.DS_Store
Thumbs.db

# IDE 配置文件(可选)
.vscode/
.idea/

🚀 后续优化建议

短期 (已完成)

  • 解决 SSH 认证问题,切换到 HTTPS
  • 移除大文件,解决推送限制
  • 创建问题解决记录
  • 验证推送拉取功能正常
  • 更新 .gitignore 防止类似问题

长期 (可选)

  • 学习并正确配置 SSH 密钥 (如需要)
  • 熟悉 Windows 下的 Git 最佳实践
  • 考虑使用 Git Credential Manager 简化认证
  • 学习 Git LFS 用于管理必要的大文件
  • 建立项目文件管理规范

📋 ADHD 友好的操作清单

下次遇到类似问题时的检查步骤:

  1. 确认错误类型 (网络 vs 认证 vs 权限 vs 文件大小)
  2. 检查 git remote -v 输出
  3. 如果是认证问题,优先尝试 HTTPS 方案
  4. 如果是大文件问题,检查是否有 >100MB 的文件
  5. 移除不必要的大文件,更新 .gitignore
  6. 验证解决方案有效性
  7. 记录解决过程 (就像这个文档)

大文件问题专项检查清单

  1. 运行 git status 查看待提交文件
  2. 使用 find . -size +100M 查找大文件 (Linux/Mac)
  3. 或使用 forfiles /s /m *.* /c "cmd /c if @fsize gtr 104857600 echo @path @fsize" (Windows)
  4. 将大文件路径添加到 .gitignore
  5. 使用 git rm --cached 从索引中移除
  6. 关键步骤: 检查 git log 确认大文件不在历史记录中
  7. 如果历史记录包含大文件,使用 git filter-repo 清理
  8. 创建备份分支防止数据丢失
  9. 提交并推送更改
  10. 验证推送成功,无大文件错误

Git历史问题诊断清单

  • 错误信息是否提到"历史记录中的文件"
  • 运行 git log --oneline 检查最近的提交
  • 确认大文件在哪个提交中被添加
  • 评估是否需要保留这些提交中的其他文件
  • 选择合适的清理策略(filter-repo vs 重置)

🎉 成功标志

  • ✅ 解决了 SSH 认证问题,Git 推送拉取正常工作
  • ✅ 解决了大文件限制问题,移除了超大文件
  • ✅ VS Code 源代码管理功能恢复
  • ✅ SSH 连接测试通过
  • ✅ 创建了完整的复盘记录
  • ✅ 更新了 .gitignore 防止类似问题再次发生

📝 备注

这次问题解决体现了"分阶段解决复杂问题"的原则:

  1. 第一阶段:解决认证问题 (SSH → HTTPS)
  2. 第二阶段A:尝试移除大文件 (git rm --cached)
  3. 第二阶段B:发现历史记录问题,需要更深层清理
  4. 第二阶段C:使用高级工具清理Git历史记录

关键教训

  • git rm --cached 只能解决当前索引问题,不能清理历史记录
  • GitHub 检查整个推送历史,包括所有提交中的文件大小
  • 大文件处理需要区分"当前移除"和"历史清理"两个层面
  • 在进行破坏性操作前,务必备份有价值的数据

虽然 SSH 密钥是更安全的方式,但在解决紧急问题时,HTTPS 方案更快更可靠。同时,合理的文件管理和 .gitignore 配置是 Git 项目管理的基础。

记住:

  • 遇到技术问题时,先让系统跑起来,再考虑优化!
  • 分步骤解决复杂问题,每次只专注一个问题!
  • Git历史问题比表面问题更复杂,需要更谨慎的处理! 🎯