mcpField
G
git-troubleshooting

git-troubleshooting

github.com/geoffjay开发8345 次安装52 周前更新
代码仓库

关于 git-troubleshooting

该技能提供 Git 故障诊断与恢复指导,涵盖提交或分支找回、合并与变基冲突、仓库损坏及常见错误。适合处理 Git 异常并需要操作步骤和诊断命令的开发者。

主要功能

  1. 01通过 reflog 找回提交或分支
  2. 02处理 detached HEAD 状态
  3. 03解决合并与变基问题
  4. 04检查并修复仓库损坏
  5. 05诊断认证、子模块及性能问题
  6. 06提供常见错误的处理方法

适用场景

  1. 01意外重置后恢复提交
  2. 02处理合并冲突或失败的变基
  3. 03排查仓库损坏或 Git 认证问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/geoffjay/claude-plugins --skill git-troubleshooting

安装后在 Claude Code 中输入/git-troubleshooting确认已加载。

详细介绍

Git 故障排除技能

本技能提供全面的指导,帮助诊断和解决 git 问题、从错误中恢复、修复损坏的仓库,以及处理常见错误情形。

适用情形

在以下情况启用本技能:

  • 遇到 git 错误消息
  • 恢复丢失的提交或分支
  • 修复损坏的仓库
  • 解决分离 HEAD 状态
  • 处理失败的合并或变基
  • 诊断仓库问题
  • 从强制推送中恢复
  • 修复身份验证问题

恢复丢失的提交

使用 Reflog
# View reflog (local history of HEAD)
git reflog

# View reflog for specific branch
git reflog show branch-name

# Output example:
# abc123 HEAD@{0}: commit: feat: add authentication
# def456 HEAD@{1}: commit: fix: resolve bug
# ghi789 HEAD@{2}: reset: moving to HEAD~1

# Recover lost commit
git cherry-pick abc123

# Or create branch from lost commit
git branch recovered-branch abc123

# Or reset to lost commit
git reset --hard abc123
查找悬空提交
# Find all unreachable objects
git fsck --lost-found

# Output:
# dangling commit abc123
# dangling blob def456

# View dangling commit
git show abc123

# Recover dangling commit
git branch recovered abc123

# Or merge it
git merge abc123
恢复已删除的分支
# Find branch commit in reflog
git reflog

# Look for branch deletion:
# abc123 HEAD@{5}: checkout: moving from feature-branch to main

# Recreate branch
git branch feature-branch abc123

# Or if branch was merged before deletion
git log --all --oneline | grep "feature"
git branch feature-branch def456
重置后恢复
# After accidental reset --hard
git reflog

# Find commit before reset:
# abc123 HEAD@{0}: reset: moving to HEAD~5
# def456 HEAD@{1}: commit: last good commit

# Restore to previous state
git reset --hard def456

# Or create recovery branch
git branch recovery def456

解决分离 HEAD

了解分离 HEAD
# Detached HEAD state occurs when:
git checkout abc123
git checkout v1.0.0
git checkout origin/main

# HEAD is not attached to any branch
从分离 HEAD 中恢复
# Check current state
git status
# HEAD detached at abc123

# Option 1: Create new branch
git checkout -b new-branch-name

# Option 2: Return to previous branch
git checkout main

# Option 3: Reattach HEAD to branch
git checkout -b temp-branch
git checkout main
git merge temp-branch

# If you made commits in detached HEAD:
git reflog
# Find the commits
git branch recovery-branch abc123
避免分离 HEAD
# Instead of checking out tag directly
git checkout -b release-v1.0 v1.0.0

# Instead of checking out remote branch
git checkout -b local-feature origin/feature-branch

# Check if HEAD is detached
git symbolic-ref -q HEAD && echo "attached" || echo "detached"

修复合并冲突

了解冲突标记
<<<<<<< HEAD (Current Change)
int result = add(a, b);
||||||| merged common ancestors (Base)
int result = sum(a, b);
=======
int sum = calculate(a, b);
>>>>>>> feature-branch (Incoming Change)
基本冲突解决方法
# When merge conflict occurs
git status
# both modified: file.go

# View conflict
cat file.go

# Option 1: Keep ours (current branch)
git checkout --ours file.go
git add file.go

# Option 2: Keep theirs (incoming branch)
git checkout --theirs file.go
git add file.go

# Option 3: Manual resolution
# Edit file.go to resolve conflicts
git add file.go

# Complete merge
git commit
中止操作
# Abort merge
git merge --abort

# Abort rebase
git rebase --abort

# Abort cherry-pick
git cherry-pick --abort

# Abort revert
git revert --abort

# Abort am (apply mailbox)
git am --abort
解决复杂冲突
# Use merge tool
git mergetool

# View three-way diff
git diff --ours
git diff --theirs
git diff --base

# Show conflicts with context
git diff --check

# List conflicted files
git diff --name-only --diff-filter=U

# After resolving all conflicts
git add .
git commit

修复失败的变基

从失败的变基中恢复
# Abort current rebase
git rebase --abort

# Find state before rebase
git reflog
# abc123 HEAD@{1}: rebase: checkout main

# Return to pre-rebase state
git reset --hard HEAD@{1}

# Alternative: use ORIG_HEAD
git reset --hard ORIG_HEAD
变基冲突
# During rebase conflict
git status
# both modified: file.go

# Resolve conflicts
# Edit file.go
git add file.go
git rebase --continue

# Skip problematic commit
git rebase --skip

# Edit commit during rebase
git commit --amend
git rebase --continue
变基到错误的分支
# Find original branch point
git reflog

# Reset to before rebase
git reset --hard HEAD@{5}

# Rebase onto correct branch
git rebase correct-branch

仓库损坏

检测损坏
# Check repository integrity
git fsck --full

# Check connectivity
git fsck --connectivity-only

# Verify pack files
git verify-pack -v .git/objects/pack/*.idx
修复损坏的对象
# Remove corrupted object
rm .git/objects/ab/cd1234...

# Try to recover from remote
git fetch origin

# Rebuild object database
git gc --prune=now

# Aggressive cleanup
git gc --aggressive --prune=now
修复索引损坏
# Remove corrupted index
rm .git/index

# Rebuild index
git reset

# Or reset to HEAD
git reset --hard HEAD
从损坏的 pack 文件中恢复
# Unpack corrupted pack
git unpack-objects < .git/objects/pack/pack-*.pack

# Remove corrupted pack
rm .git/objects/pack/pack-*

# Repack repository
git repack -a -d

# Verify integrity
git fsck --full

修复引用

损坏的分支引用
# View all references
git show-ref

# Manual reference fix
echo "abc123def456" > .git/refs/heads/branch-name

# Or use update-ref
git update-ref refs/heads/branch-name abc123

# Delete corrupted reference
git update-ref -d refs/heads/bad-branch
修复 HEAD 引用
# HEAD is corrupted or missing
echo "ref: refs/heads/main" > .git/HEAD

# Or point to specific commit
echo "abc123def456" > .git/HEAD

# Verify HEAD
git symbolic-ref HEAD
清理过时的引用
# Remove stale remote references
git remote prune origin

# Remove all stale references
git fetch --prune

# Remove all remote branches that no longer exist
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -D

撤销更改

撤销上一次提交(保留更改)
# Soft reset (changes staged)
git reset --soft HEAD~1

# Mixed reset (changes unstaged)
git reset HEAD~1
撤销上一次提交(丢弃更改)
# Hard reset
git reset --hard HEAD~1

# Can still recover via reflog
git reflog
git reset --hard HEAD@{1}
撤销多个提交
# Reset to specific commit
git reset --hard abc123

# Revert multiple commits (creates new commits)
git revert HEAD~3..HEAD

# Interactive rebase to remove commits
git rebase -i HEAD~5
# Mark commits with 'drop' or delete lines
撤销文件更改
# Discard uncommitted changes
git checkout -- file.go

# Or in Git 2.23+
git restore file.go

# Discard staged changes
git reset HEAD file.go
git restore file.go

# Or in Git 2.23+
git restore --staged file.go
git restore file.go

# Restore file from specific commit
git checkout abc123 -- file.go
撤销公开提交
# Never use reset on public commits
# Use revert instead
git revert HEAD
git revert abc123
git revert abc123..def456

# Revert merge commit
git revert -m 1 merge-commit-hash

处理强制推送问题

强制推送后恢复
# If you were force pushed over
git reflog
# abc123 HEAD@{1}: pull: Fast-forward

# Recover your commits
git reset --hard HEAD@{1}

# Create backup branch
git branch backup-branch

# Merge with force-pushed branch
git pull origin main
git merge backup-branch
避免强制推送造成损害
# Always fetch before force push
git fetch origin

# View what would be lost
git log origin/main..HEAD

# Force push with lease (safer)
git push --force-with-lease origin main

# Configure push protection
git config --global push.default simple

大文件问题

查找大文件
# Find large files in history
git rev-list --objects --all | \
  git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
  awk '/^blob/ {print substr($0,6)}' | \
  sort --numeric-sort --key=2 | \
  tail -10

# Verify current large files
git ls-files | xargs ls -lh | sort -k 5 -h -r | head -20
移除大文件
# Using git-filter-repo (recommended)
git filter-repo --path large-file.bin --invert-paths

# Using BFG
bfg --strip-blobs-bigger-than 100M

# After removal
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push --force origin main
避免大文件问题
# Configure pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
if git diff --cached --name-only | xargs du -h | awk '$1 ~ /M$|G$/' | grep .; then
    echo "Error: Large file detected"
    exit 1
fi
EOF

chmod +x .git/hooks/pre-commit

身份验证问题

SSH 密钥问题
# Test SSH connection
ssh -T [email protected]

# Check SSH key
ls -la ~/.ssh

# Generate new SSH key
ssh-keygen -t ed25519 -C "[email protected]"

# Add key to ssh-agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# Configure SSH
cat > ~/.ssh/config << EOF
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
EOF
HTTPS 身份验证
# Cache credentials
git config --global credential.helper cache
git config --global credential.helper 'cache --timeout=3600'

# Or use store (less secure)
git config --global credential.helper store

# Update remote URL
git remote set-url origin https://github.com/user/repo.git

# Use personal access token
git clone https://[email protected]/user/repo.git
权限被拒绝
# Check remote URL
git remote -v

# Change to SSH
git remote set-url origin [email protected]:user/repo.git

# Change to HTTPS
git remote set-url origin https://github.com/user/repo.git

# Verify permissions
ls -la .git/
chmod -R u+rw .git/

子模块问题

子模块未初始化
# Initialize submodules
git submodule init
git submodule update

# Or in one command
git submodule update --init --recursive
子模块中的分离 HEAD
# Enter submodule
cd submodule-dir

# Create branch
git checkout -b main

# Or attach to existing branch
git checkout main
git pull origin main

# Update parent repo
cd ..
git add submodule-dir
git commit -m "chore: update submodule"
子模块冲突
# Check submodule status
git submodule status

# Reset submodule
git submodule update --init --force

# Remove and re-add submodule
git submodule deinit -f path/to/submodule
git rm -f path/to/submodule
git submodule add <url> path/to/submodule

性能问题

操作缓慢
# Optimize repository
git gc --aggressive

# Repack efficiently
git repack -a -d --depth=250 --window=250

# Prune old objects
git prune --expire now

# Clean up unnecessary files
git clean -fdx
仓库过大
# Shallow clone
git clone --depth 1 <url>

# Fetch only one branch
git clone --single-branch --branch main <url>

# Partial clone
git clone --filter=blob:none <url>

# Sparse checkout
git sparse-checkout init --cone
git sparse-checkout set folder1 folder2
内存问题
# Increase memory limits
git config --global pack.windowMemory "100m"
git config --global pack.packSizeLimit "100m"
git config --global pack.threads "1"

# Disable delta compression temporarily
git config --global pack.compression 0

常见错误消息

“fatal: refusing to merge unrelated histories”
# Allow merging unrelated histories
git pull origin main --allow-unrelated-histories
“fatal: not a git repository”
# Reinitialize repository
git init

# Or check if .git directory exists
ls -la .git

# Restore from backup if corrupted
“error: Your local changes would be overwritten”
# Stash changes
git stash
git pull
git stash pop

# Or discard changes
git reset --hard HEAD
git pull
“error: failed to push some refs”
# Fetch and merge first
git pull origin main

# Or rebase
git pull --rebase origin main

# Force push (dangerous)
git push --force origin main

# Safer force push
git push --force-with-lease origin main
“fatal: unable to access: SSL certificate problem”
# Disable SSL verification (not recommended)
git config --global http.sslVerify false

# Or update SSL certificates
git config --global http.sslCAInfo /path/to/cacert.pem

诊断命令

仓库健康检查
# Full integrity check
git fsck --full --strict

# Check connectivity
git fsck --connectivity-only

# Verify objects
git verify-pack -v .git/objects/pack/*.idx

# Check reflog
git reflog expire --dry-run --all

# Analyze repository
git count-objects -vH
调试信息
# Enable verbose logging
GIT_TRACE=1 git status
GIT_TRACE=1 git pull

# Debug specific operations
GIT_TRACE_PACKET=1 git fetch
GIT_TRACE_PERFORMANCE=1 git diff
GIT_CURL_VERBOSE=1 git push

# Configuration debugging
git config --list --show-origin
git config --list --show-scope

预防策略

  1. 定期备份: 在进行高风险操作前创建备份分支
  2. 使用 Reflog: Reflog 是你的安全网,请保持其整洁
  3. 启用 Rerere: 重用已记录的冲突解决方案
  4. 保护分支: 使用分支保护规则
  5. 提交前钩子: 在提交前验证内容
  6. 定期维护: 定期运行 git gc
  7. 强制推送前测试: 始终使用 --dry-run 验证
  8. 沟通: 将可能造成影响的操作告知团队
  9. 学习 Git 内部机制: 了解 git 的工作原理可避免问题
  10. 保持 Git 更新: 使用最新的稳定版本

资源

assets/ 目录中提供了其他故障排除指南:

  • troubleshooting/ - 逐步恢复流程
  • scripts/ - 诊断和恢复脚本
  • checklists/ - 问题诊断工作流

请参阅 references/ 目录中的:

  • Git 错误消息数据库
  • 恢复流程文档
  • Git 内部结构指南
  • 常见陷阱文档

评论

支持 Markdown