Skip to content

Git 问题诊断

概述

在使用 Git 的过程中,难免会遇到各种问题。掌握有效的诊断方法可以帮助快速定位和解决问题。本指南将介绍常见的诊断方法、日志查看、调试技巧和问题定位。

常见诊断方法

检查 Git 状态

bash
# 查看仓库状态
git status

# 详细状态
git status -v

# 短格式输出
git status -s

# 查看分支信息
git branch -vv

# 查看远程仓库
git remote -v

检查 Git 配置

bash
# 查看所有配置
git config --list

# 查看特定配置
git config user.name
git config user.email

# 查看系统配置
git config --system --list

# 查看全局配置
git config --global --list

# 查看本地配置
git config --local --list

检查连接

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

# 测试 HTTPS 连接
curl -I https://github.com

# 检查网络
ping github.com
traceroute github.com

# 检查端口
nc -zv github.com 22
nc -zv github.com 443

检查文件状态

bash
# 查看文件差异
git diff

# 查看暂存差异
git diff --staged

# 查看特定文件
git diff path/to/file

# 查看文件历史
git log --follow path/to/file

# 查看文件变更记录
git log -p path/to/file

日志查看

Git 日志

bash
# 查看提交历史
git log

# 单行显示
git log --oneline

# 图形显示
git log --graph --oneline --all

# 查看最近 N 条
git log -n 10

# 查看特定作者
git log --author="username"

# 查看特定时间
git log --since="2024-01-01"
git log --until="2024-12-31"
git log --after="1 week ago"

# 查看特定文件
git log -- path/to/file

# 查看合并提交
git log --merges

# 查看提交统计
git log --stat

# 查看提交内容
git log -p

Git Reflog

bash
# 查看引用日志
git reflog

# 查看所有引用
git reflog --all

# 查看特定分支
git reflog show branch-name

# 查看最近 N 条
git reflog -n 10

# 恢复到特定提交
git reset --hard HEAD@{n}

Git fsck

bash
# 检查仓库完整性
git fsck

# 检查所有对象
git fsck --full

# 检查未引用对象
git fsck --unreachable

# 检查悬挂对象
git fsck --dangling

# 检查并修复
git fsck --full --no-dangling

系统日志

bash
# 查看系统日志
# Linux
tail -f /var/log/syslog
journalctl -f

# macOS
log stream

# 查看 Git 相关日志
grep -i git /var/log/syslog

# 查看 SSH 日志
tail -f /var/log/auth.log

调试技巧

Git 调试模式

bash
# 启用详细输出
GIT_TRACE=1 git status

# 启用调试
GIT_TRACE=1 GIT_SSH_COMMAND="ssh -vvv" git push

# 查看 Git 执行过程
GIT_TRACE_PERFORMANCE=1 git status

# 查看配置来源
GIT_TRACE_CONFIG=1 git config --list

SSH 调试

bash
# 测试 SSH 连接(详细)
ssh -vT git@github.com

# 更详细的调试
ssh -vvvT git@github.com

# 检查 SSH 配置
ssh -G github.com

# 检查已知主机
cat ~/.ssh/known_hosts

# 检查 SSH Agent
ssh-add -l

网络调试

bash
# 使用代理
git config --global http.proxy http://proxy:port
git config --global https.proxy https://proxy:port

# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy

# 查看代理设置
git config --global --get http.proxy

# 使用自定义 CA
git config --global http.sslCAInfo /path/to/ca.crt

# 禁用 SSL 验证(不推荐)
git config --global http.sslVerify false

Git Hooks 调试

bash
# 手动运行 hook
.git/hooks/pre-commit

# 添加调试输出
#!/bin/bash
set -x
echo "Running pre-commit hook"

# 检查 hook 权限
ls -la .git/hooks/

# 添加执行权限
chmod +x .git/hooks/pre-commit

问题定位

分支问题

bash
# 查看所有分支
git branch -a

# 查看分支跟踪信息
git branch -vv

# 查看分支差异
git diff main..feature

# 查看分支共同祖先
git merge-base main feature

# 查看分支历史
git log --graph --oneline --all

# 检查分支是否已合并
git branch --merged main
git branch --no-merged main

提交问题

bash
# 查看提交详情
git show <commit-hash>

# 查看提交内容
git show --stat <commit-hash>

# 查看提交的文件变更
git show --name-only <commit-hash>

# 查看提交引入的问题
git bisect start
git bisect bad HEAD
git bisect good <good-commit>
# Git 会自动定位问题提交

# 结束 bisect
git bisect reset

合并问题

bash
# 查看合并状态
git status

# 查看冲突文件
git diff --name-only --diff-filter=U

# 查看冲突内容
git diff

# 查看合并基础
git merge-base HEAD MERGE_HEAD

# 中止合并
git merge --abort

# 继续合并
git merge --continue

远程问题

bash
# 查看远程仓库
git remote -v

# 查看远程分支
git branch -r

# 查看远程分支详情
git remote show origin

# 获取远程更新
git fetch origin

# 查看本地和远程差异
git diff main origin/main

# 查看远程分支跟踪
git branch -vv

# 清理远程分支引用
git remote prune origin

性能问题

bash
# 检查仓库大小
du -sh .git

# 检查大文件
git rev-list --objects --all | \
  git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
  sed -n 's/^blob //p' | \
  sort --numeric-sort --key=2 | \
  tail -n 10

# 检查对象数量
git count-objects -v

# 优化仓库
git gc

# 深度优化
git gc --aggressive

# 清理未引用对象
git prune

# 清理 reflog
git reflog expire --expire=now --all

常用诊断脚本

仓库诊断脚本

bash
#!/bin/bash
# diagnose.sh

echo "=== Git 仓库诊断 ==="
echo ""

echo "1. 基本信息"
echo "Git 版本: $(git --version)"
echo "当前分支: $(git branch --show-current)"
echo "工作目录: $(pwd)"
echo ""

echo "2. 仓库状态"
git status -s
echo ""

echo "3. 远程仓库"
git remote -v
echo ""

echo "4. 最近提交"
git log --oneline -5
echo ""

echo "5. 未推送提交"
git log origin/$(git branch --show-current)..HEAD --oneline
echo ""

echo "6. 未合并分支"
git branch --no-merged main
echo ""

echo "7. 仓库大小"
du -sh .git
echo ""

echo "8. 对象统计"
git count-objects -v
echo ""

echo "9. 检查完整性"
git fsck --no-dangling
echo ""

echo "诊断完成!"

连接诊断脚本

bash
#!/bin/bash
# check-connection.sh

echo "=== Git 连接诊断 ==="
echo ""

echo "1. 测试 GitHub SSH 连接"
ssh -T git@github.com 2>&1 | head -1
echo ""

echo "2. 测试 GitHub HTTPS 连接"
curl -I https://github.com 2>&1 | head -1
echo ""

echo "3. 检查 SSH 密钥"
ls -la ~/.ssh/*.pub 2>/dev/null || echo "未找到 SSH 公钥"
echo ""

echo "4. 检查 SSH Agent"
ssh-add -l 2>&1 || echo "SSH Agent 未运行或无密钥"
echo ""

echo "5. 检查 Git 配置"
git config --global --list | grep -E "(user|credential|proxy)"
echo ""

echo "6. 检查网络"
ping -c 3 github.com 2>&1 | tail -2
echo ""

echo "诊断完成!"

性能诊断脚本

bash
#!/bin/bash
# performance-check.sh

echo "=== Git 性能诊断 ==="
echo ""

echo "1. 仓库大小"
du -sh .git
echo ""

echo "2. 对象统计"
git count-objects -v
echo ""

echo "3. 大文件 (>1MB)"
git rev-list --objects --all | \
  git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
  sed -n 's/^blob //p' | \
  awk '$2 > 1048576 {print $2/1048576 " MB", $3}' | \
  sort -rn | \
  head -10
echo ""

echo "4. 分支数量"
git branch -a | wc -l
echo ""

echo "5. 提交数量"
git rev-list --all | wc -l
echo ""

echo "6. 检查大包文件"
ls -lh .git/objects/pack/*.pack 2>/dev/null || echo "无 pack 文件"
echo ""

echo "诊断完成!"

问题分类

按严重程度

yaml
严重级别:
  紧急:
    - 无法推送/拉取
    - 数据丢失
    - 仓库损坏
    
:
    - 合并冲突
    - 分支问题
    - 权限问题
    
:
    - 性能问题
    - 配置问题
    - 工作流问题
    
:
    - 界面问题
    - 提示信息
    - 优化建议

按类型

yaml
问题类型:
  网络:
    - 连接超时
    - 认证失败
    - 代理问题
    
  存储:
    - 磁盘空间
    - 仓库损坏
    - 大文件问题
    
  权限:
    - 访问拒绝
    - 权限不足
    - 认证问题
    
  操作:
    - 合并冲突
    - 分支问题
    - 提交问题

总结

有效的问题诊断需要:

诊断工具:

  • Git 内置命令
  • 系统工具
  • 自定义脚本

诊断方法:

  • 检查状态
  • 查看日志
  • 调试模式

问题定位:

  • 分类问题
  • 逐步排查
  • 记录解决方案

通过系统的诊断方法,可以快速定位和解决 Git 使用中的各种问题。