⚙️ Git大师课:解锁Git的全部潜力
专业洞察 :GitHub数据显示,仅15%的开发者使用Git超过其50%的功能 。掌握高级Git技巧能让你的开发效率提升300% ,问题排查速度加快400%。
🔍 第一章:Git内部机制深度解析
1.1 Git对象模型:数据存储的奥秘
存储方式
压缩存储
通过SHA-1哈希寻址
增量存储
仅存储差异
对象打包
减少文件数量
Git对象存储层次
提交对象 Commit
树对象 Tree
blob对象 文件内容
树对象 子目录
blob对象 子文件
父提交指针
标签对象 Tag
1.1.1 探索.git目录结构
bash
# 深入探索.git目录
tree .git -L 3 -I "*.sample"
# 输出:
.git
├── HEAD # 当前分支引用
├── config # 仓库配置
├── description # 仓库描述
├── hooks # 钩子脚本目录
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ └── ...
├── index # 暂存区索引文件
├── info # 额外信息
│ └── exclude # 仓库级别.gitignore
├── logs # 引用日志
│ ├── HEAD
│ └── refs
│ ├── heads
│ └── remotes
├── objects # Git对象数据库 ★核心
│ ├── 00
│ ├── 01
│ ├── ...
│ ├── info
│ └── pack
└── refs # 引用指针
├── heads # 本地分支
├── remotes # 远程分支
└── tags # 标签
# 查看对象内容
echo "Hello Git" > test.txt
git add test.txt
# 获取blob对象的SHA-1
BLOB_SHA=$(git hash-object test.txt)
echo "Blob SHA: $BLOB_SHA"
# 查看对象类型和内容
git cat-file -t $BLOB_SHA # 输出: blob
git cat-file -p $BLOB_SHA # 输出: Hello Git
# 查看暂存区索引
git ls-files --stage
# 100644 5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689 0 test.txt
1.1.2 Git对象存储格式详解
bash
# 手动创建和查看Git对象
# 1. 创建blob对象
echo -n "Hello, Git Internals!" | git hash-object -w --stdin
# 输出: c6a0a8e6c7b4e4d4b4e6c7b4e4d4b4e6c7b4e4d4
# 2. 创建tree对象
mkdir -p test-dir
echo "File in subdirectory" > test-dir/subfile.txt
git add .
TREE_SHA=$(git write-tree)
echo "Tree SHA: $TREE_SHA"
# 3. 创建commit对象
COMMIT_SHA=$(echo "First commit" | git commit-tree $TREE_SHA)
echo "Commit SHA: $COMMIT_SHA"
# 4. 查看对象原始内容
# blob对象:内容直接存储
git cat-file -p $BLOB_SHA | hexdump -C
# tree对象:权限 类型 SHA-1 文件名
git cat-file -p $TREE_SHA
# commit对象:树指针、父提交、作者、提交者、提交信息
git cat-file -p $COMMIT_SHA
# 5. 对象压缩(pack文件)
git gc # 垃圾回收和压缩
ls -la .git/objects/pack/
# -r--r--r-- 1 user staff 2.5K Jan 18 10:00 pack-abc123.idx
# -r--r--r-- 1 user staff 8.7K Jan 18 10:00 pack-abc123.pack
1.2 Git引用系统:指针的智慧
HEAD
refs/heads/main
提交对象
父提交
...
refs/remotes/origin/main
远程提交
refs/tags/v1.0.0
标签提交
符号引用 SYMREF
相对引用
1.2.1 引用类型详解
bash
# 查看所有引用
find .git/refs -type f | xargs ls -la
# HEAD引用(特殊引用)
cat .git/HEAD
# ref: refs/heads/main # 符号引用
# 分支引用
cat .git/refs/heads/main
# abc123def456... # 直接指向提交的SHA-1
# 远程跟踪分支
cat .git/refs/remotes/origin/main
# 标签引用
cat .git/refs/tags/v1.0.0
# 创建自定义引用
git update-ref refs/mystuff/my-ref abc1234
git show-ref --heads --tags # 查看特定引用
1.2.2 高级引用操作
bash
# 1. 相对引用语法
git show HEAD # 当前提交
git show HEAD^ # 父提交
git show HEAD^^ # 祖父提交
git show HEAD~3 # 向上3代提交
git show HEAD@{2} # HEAD的第3个前身
git show HEAD@{yesterday} # 昨天的HEAD
git show HEAD@{2.weeks.ago}
# 2. 提交范围语法
git log main..feature # 在feature但不在main的提交
git log feature..main # 在main但不在feature的提交
git log feature...main # 在两分支不同的提交
git log --since="2 weeks ago"
git log --until="2024-01-01"
git log --grep="bugfix" # 搜索提交信息
# 3. 引用日志(救命稻草)
git reflog
# 输出:
# abc1234 HEAD@{0}: commit: Add new feature
# def5678 HEAD@{1}: pull origin main: Fast-forward
# ghi9012 HEAD@{2}: reset: moving to HEAD~1
# 恢复误删的分支
git checkout -b recovered-feature HEAD@{2}
# 4. 高级查找
# 查找引入bug的提交
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
# Git会自动进行二分查找...
git bisect reset
# 查找删除某行代码的提交
git log -S "removedFunctionName" --oneline
git log -L 10,20:file.js # 查看文件第10-20行的历史
⚡ 第二章:Git性能优化高级技巧
2.1 大型仓库性能优化
大型仓库问题
克隆缓慢
操作延迟
存储膨胀
解决方案
解决方案
解决方案
浅克隆
--depth 1
部分克隆
--filter
单分支克隆
--single-branch
稀疏检出
sparse-checkout
对象池
alternates
预加载索引
core.preloadindex
定期GC
git gc
包文件优化
repack
大文件管理
Git LFS
2.2.1 智能克隆策略
bash
#!/bin/bash
# smart-clone.sh - 大型仓库智能克隆策略
REPO_URL="https://github.com/large/repository.git"
CLONE_DIR="repository"
echo "🔍 分析仓库大小..."
# 获取仓库信息(无需完整克隆)
git ls-remote --symref $REPO_URL HEAD
git ls-remote $REPO_URL | head -5
echo ""
echo "🚀 选择克隆策略:"
echo "1. 完整克隆(默认)"
echo "2. 浅克隆(只获取最新提交)"
echo "3. 单分支克隆"
echo "4. 部分克隆(按需获取)"
echo "5. 稀疏检出(只检出部分文件)"
read -p "选择 (1-5): " choice
case $choice in
1)
echo "完整克隆中..."
git clone $REPO_URL $CLONE_DIR
;;
2)
echo "浅克隆中(深度1)..."
git clone --depth 1 $REPO_URL $CLONE_DIR
# 后续需要更多历史时
cd $CLONE_DIR
git fetch --deepen 10 # 获取额外10个提交
;;
3)
echo "单分支克隆中..."
git clone --single-branch --branch main $REPO_URL $CLONE_DIR
;;
4)
echo "部分克隆中(只获取blob)..."
git clone --filter=blob:none $REPO_URL $CLONE_DIR
# 按需获取文件内容
cd $CLONE_DIR
git checkout HEAD -- path/to/large-file.bin
;;
5)
echo "稀疏克隆中..."
git clone --no-checkout $REPO_URL $CLONE_DIR
cd $CLONE_DIR
# 配置稀疏检出
git sparse-checkout init --cone
git sparse-checkout set src/ docs/
# 检出指定文件
git checkout main
;;
*)
echo "使用默认完整克隆"
git clone $REPO_URL $CLONE_DIR
;;
esac
echo "✅ 克隆完成"
du -sh $CLONE_DIR # 查看占用空间
2.2.2 仓库维护与优化
bash
#!/bin/bash
# git-maintenance.sh - Git仓库维护工具
echo "🧹 Git仓库维护工具"
echo "=================="
# 1. 垃圾回收
echo "1. 运行垃圾回收..."
git gc --auto
if [ $? -eq 0 ]; then
echo " ✅ 自动GC已运行"
else
echo " 🔄 运行完整GC..."
git gc --aggressive --prune=now
fi
# 2. 包文件重新打包
echo "2. 优化包文件..."
git repack -a -d --depth=250 --window=250
# 3. 清理无效引用
echo "3. 清理无效引用..."
git remote prune origin
git fetch --prune
git reflog expire --expire=30.days --all
# 4. 检查大文件
echo "4. 查找大文件..."
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 -10 \
| cut -c 1-12,41- \
| while read hash size file
do
echo "$size $hash $file"
done
# 5. 检查悬空对象
echo "5. 检查悬空对象..."
git fsck --unreachable | head -20
# 6. 性能诊断
echo "6. 性能诊断..."
echo " 对象数量: $(git count-objects -v | grep count | awk '{print $2}')"
echo " 包文件数量: $(find .git/objects/pack -name "*.pack" 2>/dev/null | wc -l)"
echo " 松散对象: $(find .git/objects -type f | grep -v pack | wc -l)"
# 7. 钩子优化
echo "7. 优化钩子性能..."
if [ -f .git/hooks/pre-commit ]; then
echo " 预提交钩子存在,检查性能..."
time .git/hooks/pre-commit
fi
echo "✅ 维护完成"
2.3 Git LFS(大文件存储)专家级配置
yaml
# .lfsconfig - Git LFS高级配置
[lfs]
# 跟踪特定模式的文件
url = "https://git-lfs.company.com"
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge --skip -- %f
process = git-lfs filter-process
required = true
# .gitattributes - 详细跟踪配置
# 图像文件
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
# 视频文件
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
*.avi filter=lfs diff=lfs merge=lfs -text
# 二进制文件
*.exe filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.dylib filter=lfs diff=lfs merge=lfs -text
# 数据集
*.h5 filter=lfs diff=lfs merge=lfs -text
*.pkl filter=lfs diff=lfs merge=lfs -text
*.npz filter=lfs diff=lfs merge=lfs -text
# 设计文件
*.sketch filter=lfs diff=lfs merge=lfs -text
*.fig filter=lfs diff=lfs merge=lfs -text
# 文档
*.pdf filter=lfs diff=lfs merge=lfs -text
*.pages filter=lfs diff=lfs merge=lfs -text
# 排除某些大文件(使用.gitignore)
# !*.large.png
bash
# Git LFS高级管理脚本
#!/bin/bash
# git-lfs-manager.sh
echo "📁 Git LFS管理工具"
echo "================="
case "$1" in
"install")
echo "安装Git LFS..."
git lfs install --skip-repo
echo "✅ Git LFS已安装"
;;
"track")
if [ -z "$2" ]; then
echo "用法: $0 track <文件模式>"
exit 1
fi
echo "跟踪文件模式: $2"
git lfs track "$2"
git add .gitattributes
git commit -m "chore: track $2 with Git LFS"
;;
"migrate")
echo "迁移现有大文件到LFS..."
# 查找大于10MB的文件
git lfs migrate import \
--include="*.psd,*.mp4,*.exe" \
--everything \
--above=10MB
echo "✅ 迁移完成"
;;
"status")
echo "LFS文件状态:"
git lfs status
echo ""
echo "LFS文件列表:"
git lfs ls-files
echo ""
echo "存储使用情况:"
git lfs env
;;
"cleanup")
echo "清理LFS缓存..."
git lfs prune
echo "检查孤立的LFS文件..."
git lfs fetch --all
git lfs fsck
;;
"info")
echo "LFS信息摘要:"
git lfs version
git lfs env | grep -E "(Endpoint|LocalWorkingDir|LocalGitDir)"
# 显示存储大小
echo ""
echo "存储统计:"
find .git/lfs/objects -type f 2>/dev/null | wc -l | xargs echo "LFS对象数量:"
du -sh .git/lfs/objects 2>/dev/null || echo "LFS目录不存在"
;;
*)
echo "可用命令:"
echo " install 安装Git LFS"
echo " track <模式> 跟踪文件模式"
echo " migrate 迁移现有文件"
echo " status 查看状态"
echo " cleanup 清理缓存"
echo " info 查看信息"
;;
esac
🛠️ 第三章:Git高级配置与自定义
3.1 Git配置系统深度解析
Git配置层次
系统配置 /etc/gitconfig
全局配置 ~/.gitconfig
仓库配置 .git/config
命令行配置 -c 参数
影响所有用户
影响当前用户
仅影响当前仓库
单次命令有效
优先级从低到高
最高优先级
3.1.1 专业级Git配置模板
ini
# ~/.gitconfig - 专业开发者配置模板
[user]
name = 你的姓名
email = 你的邮箱@company.com
signingkey = ABCD1234 # GPG签名密钥
[core]
editor = code --wait # VS Code作为编辑器
autocrlf = input # macOS/Linux
# autocrlf = true # Windows
excludesfile = ~/.gitignore_global
pager = delta # 使用delta作为分页器
fsmonitor = true # 文件系统监视器
preloadindex = true # 预加载索引提升性能
fscache = true # 文件系统缓存
[alias]
# 基础别名
co = checkout
br = branch
ci = commit
st = status
df = diff
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
# 高级别名
undo = reset HEAD~1
amend = commit --amend --no-edit
wip = !git add -A && git commit -m \"WIP\"
unwip = !git log -n 1 --oneline | grep -q WIP && git reset HEAD~1
cleanup = "!f() { git branch --merged ${1-main} | grep -v \" ${1-main}$\" | xargs -r git branch -d; }; f"
# 统计别名
stat = log --stat --summary
count = shortlog -sn
lines = "!f() { git log --author=\"$1\" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf \"added lines: %s, removed lines: %s, total lines: %s\\n\", add, subs, loc }' -; }; f"
[merge]
tool = vscode
conflictstyle = diff3 # 显示共同祖先
[mergetool "vscode"]
cmd = code --wait $MERGED
[difftool "vscode"]
cmd = code --wait --diff $LOCAL $REMOTE
[pull]
rebase = true # 默认使用rebase而不是merge
[push]
default = current
autoSetupRemote = true
[commit]
gpgsign = true # 启用GPG签名
verbose = true # 显示差异
[color]
ui = auto
diff = auto
status = auto
branch = auto
interactive = auto
[interactive]
diffFilter = delta --color-only
[delta]
features = side-by-side line-numbers decorations
syntax-theme = GitHub
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
[init]
defaultBranch = main
[gpg]
program = gpg
[github]
user = your-username
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work # 工作相关配置
[includeIf "gitdir:~/personal/"]
path = ~/.gitconfig-personal # 个人项目配置
3.1.2 条件配置与多环境管理
bash
#!/bin/bash
# setup-git-profiles.sh - 多环境Git配置
echo "🎭 设置Git多环境配置"
# 创建工作配置
cat > ~/.gitconfig-work << 'EOF'
[user]
name = 你的工作姓名
email = you@company.com
signingkey = WORK_KEY_ID
[core]
sshCommand = ssh -i ~/.ssh/id_ed25519_work
[commit]
template = ~/.gitmessage-work
[include]
path = ~/.gitconfig-common
EOF
# 创建个人配置
cat > ~/.gitconfig-personal << 'EOF'
[user]
name = 你的个人姓名
email = you@gmail.com
signingkey = PERSONAL_KEY_ID
[core]
sshCommand = ssh -i ~/.ssh/id_ed25519_personal
[commit]
template = ~/.gitmessage-personal
[include]
path = ~/.gitconfig-common
EOF
# 创建共享通用配置
cat > ~/.gitconfig-common << 'EOF'
[alias]
# 通用别名
co = checkout
br = branch
ci = commit
st = status
# 日志美化
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
# 清理合并的分支
cleanup = "!f() { git branch --merged ${1-main} | grep -v \" ${1-main}$\" | xargs -r git branch -d; }; f"
[core]
editor = code --wait
autocrlf = input
excludesfile = ~/.gitignore_global
[pull]
rebase = true
[push]
default = current
EOF
# 创建提交信息模板
cat > ~/.gitmessage-work << 'EOF'
# 工作提交模板
# 类型: feat|fix|docs|style|refactor|test|chore
# 影响范围: (可选)
# 关联工单: #123
# 标题行 (不超过50字符)
# <类型>(<影响范围>): <简短描述>
# 详细描述 (可选)
# - 说明变更原因
# - 列出主要变更
# - 描述测试情况
# 注意事项 (可选)
# - 需要数据库变更
# - 影响API接口
# - 需要文档更新
EOF
cat > ~/.gitmessage-personal << 'EOF'
# 个人项目提交
# 更灵活的格式
# 标题行
# 简短描述变更
# 详细说明 (可选)
EOF
# 创建全局.gitignore
cat > ~/.gitignore_global << 'EOF'
# 操作系统文件
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# 编辑器文件
.vscode/
.idea/
*.swp
*.swo
*~
# 日志文件
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# 运行时数据
pids
*.pid
*.seed
*.pid.lock
# 依赖目录
node_modules/
vendor/
jspm_packages/
# 构建产物
dist/
build/
*.exe
*.dll
*.so
*.dylib
# 测试相关
coverage/
.nyc_output/
# 环境文件
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# 缓存文件
.cache/
# 临时文件
tmp/
temp/
EOF
echo "✅ Git多环境配置完成"
echo ""
echo "使用方式:"
echo "1. 工作项目放在 ~/work/ 目录下"
echo "2. 个人项目放在 ~/personal/ 目录下"
echo "3. Git会自动使用对应的配置"
3.2 Git Hook高级应用
3.2.1 企业级Git Hook系统
bash
#!/bin/bash
# setup-enterprise-hooks.sh - 企业级Git Hook系统
echo "🪝 设置企业级Git Hook系统"
HOOKS_DIR=".githooks"
mkdir -p $HOOKS_DIR
# 1. 预提交钩子(质量门禁)
cat > $HOOKS_DIR/pre-commit << 'EOF'
#!/bin/bash
echo "🔍 企业级代码质量检查..."
# 配置
MAX_FILE_SIZE=5242880 # 5MB
MIN_TEST_COVERAGE=80 # 80%
# 获取变更文件
FILES=$(git diff --cached --name-only --diff-filter=ACM)
# 1. 检查文件大小
echo "检查文件大小..."
for FILE in $FILES; do
if [ -f "$FILE" ]; then
FILE_SIZE=$(stat -f%z "$FILE" 2>/dev/null || stat -c%s "$FILE" 2>/dev/null)
if [ "$FILE_SIZE" -gt "$MAX_FILE_SIZE" ]; then
echo "❌ 错误:文件 '$FILE' 大小 ($((FILE_SIZE/1024))KB) 超过 $((MAX_FILE_SIZE/1024))KB 限制"
echo "💡 建议:使用Git LFS或分割文件"
exit 1
fi
fi
done
# 2. 检查敏感信息
echo "检查敏感信息..."
SENSITIVE_PATTERNS=(
"password\s*=\s*['\"][^'\"]+['\"]"
"secret\s*=\s*['\"][^'\"]+['\"]"
"api[_-]?key\s*=\s*['\"][^'\"]+['\"]"
"BEGIN (RSA|OPENSSH) PRIVATE KEY"
"-----BEGIN PRIVATE KEY-----"
)
for FILE in $FILES; do
if [ -f "$FILE" ]; then
for PATTERN in "${SENSITIVE_PATTERNS[@]}"; do
if grep -q -E "$PATTERN" "$FILE" 2>/dev/null; then
echo "❌ 安全警告:文件 '$FILE' 可能包含敏感信息"
echo "💡 请移除敏感信息或使用环境变量"
exit 1
fi
done
fi
done
# 3. 代码质量检查(如果配置了)
if [ -f "package.json" ]; then
echo "运行代码质量检查..."
# ESLint检查
if [ -f "node_modules/.bin/eslint" ]; then
npx eslint $FILES --quiet
if [ $? -ne 0 ]; then
echo "❌ ESLint检查失败,请修复代码风格问题"
exit 1
fi
fi
# TypeScript检查
if [ -f "tsconfig.json" ]; then
npx tsc --noEmit
if [ $? -ne 0 ]; then
echo "❌ TypeScript编译错误"
exit 1
fi
fi
# 测试覆盖率检查
if [ -f "jest.config.js" ]; then
COVERAGE=$(npx jest --coverage --passWithNoTests 2>/dev/null | grep -E "All files.*%")
if [ ! -z "$COVERAGE" ]; then
echo "📊 测试覆盖率: $COVERAGE"
# 可以添加覆盖率阈值检查
fi
fi
fi
# 4. 提交信息格式检查(通过commit-msg钩子)
echo "✅ 预提交检查通过"
exit 0
EOF
# 2. 提交信息钩子
cat > $HOOKS_DIR/commit-msg << 'EOF'
#!/bin/bash
echo "📝 验证提交信息格式..."
COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# 提交信息格式正则(Conventional Commits)
PATTERN="^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .+"
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo "❌ 提交信息格式错误"
echo ""
echo "📖 正确格式:type(scope): description"
echo ""
echo "📋 类型说明:"
echo " feat 新功能"
echo " fix Bug修复"
echo " docs 文档更新"
echo " style 代码格式"
echo " refactor 代码重构"
echo " test 测试相关"
echo " chore 构建/工具"
echo " perf 性能优化"
echo " ci CI/CD"
echo " build 构建系统"
echo " revert 回滚提交"
echo ""
echo "🌰 示例:"
echo " feat(auth): add login functionality"
echo " fix(api): resolve null pointer exception"
echo " docs: update README with installation guide"
echo ""
echo "当前提交信息:"
echo " $COMMIT_MSG"
exit 1
fi
# 检查行长度
FIRST_LINE=$(echo "$COMMIT_MSG" | head -1)
if [ ${#FIRST_LINE} -gt 72 ]; then
echo "⚠️ 警告:提交标题超过72字符(当前:${#FIRST_LINE})"
echo " 建议保持在50字符以内"
fi
echo "✅ 提交信息格式正确"
exit 0
EOF
# 3. 预推送钩子
cat > $HOOKS_DIR/pre-push << 'EOF'
#!/bin/bash
echo "🚀 预推送检查..."
# 获取推送的分支
while read local_ref local_sha remote_ref remote_sha; do
if [ "$local_ref" = "refs/heads/main" ] || [ "$local_ref" = "refs/heads/master" ]; then
echo "🔒 正在推送到主分支,进行额外检查..."
# 检查是否包含WIP提交
WIP_COMMITS=$(git log --oneline origin/main..HEAD | grep -i "wip\|work in progress")
if [ ! -z "$WIP_COMMITS" ]; then
echo "❌ 错误:发现WIP提交"
echo "$WIP_COMMITS"
echo "💡 请使用 git rebase -i 移除或修改WIP提交"
exit 1
fi
# 检查是否包含fixup/squash提交
FIXUP_COMMITS=$(git log --oneline origin/main..HEAD | grep -i "fixup\|squash")
if [ ! -z "$FIXUP_COMMITS" ]; then
echo "❌ 错误:发现fixup/squash提交"
echo "$FIXUP_COMMITS"
echo "💡 请使用 git rebase -i 整理提交历史"
exit 1
fi
fi
done
echo "✅ 预推送检查通过"
exit 0
EOF
# 4. 提交后钩子
cat > $HOOKS_DIR/post-commit << 'EOF'
#!/bin/bash
echo "📨 提交后处理..."
# 获取最新提交信息
COMMIT_MSG=$(git log -1 --pretty=%B)
COMMIT_HASH=$(git log -1 --pretty=%H)
# 生成变更日志片段
if [ ! -d ".changelogs" ]; then
mkdir -p ".changelogs/unreleased"
fi
# 解析提交类型和描述
if echo "$COMMIT_MSG" | grep -qE "^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)"; then
TYPE=$(echo "$COMMIT_MSG" | sed -E 's/^([^(:]+).*/\1/')
DESCRIPTION=$(echo "$COMMIT_MSG" | sed -E 's/^[^:]+:? //')
# 创建变更日志条目
TIMESTAMP=$(date +%Y%m%d%H%M%S)
cat > ".changelogs/unreleased/${TIMESTAMP}-${COMMIT_HASH:0:7}.md" << EOL
## $TYPE
- $DESCRIPTION ([${COMMIT_HASH:0:7}](commit/$COMMIT_HASH))
EOL
echo "📝 已生成变更日志片段"
fi
# 发送通知(可选)
# if [ -f ".slack-webhook" ]; then
# WEBHOOK_URL=$(cat .slack-webhook)
# curl -X POST -H 'Content-type: application/json' \
# --data "{\"text\":\"New commit: $COMMIT_MSG\"}" \
# $WEBHOOK_URL
# fi
echo "✅ 提交后处理完成"
EOF
# 5. 安装钩子
chmod +x $HOOKS_DIR/*
git config core.hooksPath $HOOKS_DIR
echo "✅ 企业级Git Hook系统安装完成"
echo ""
echo "📁 Hook目录: $HOOKS_DIR/"
echo "📋 已安装钩子:"
ls -la $HOOKS_DIR/
3.2.2 Git Hook管理工具
bash
#!/bin/bash
# git-hook-manager.sh - Git Hook管理工具
HOOKS_DIR=".githooks"
case "$1" in
"install")
echo "安装Git Hooks..."
git config core.hooksPath "$HOOKS_DIR"
chmod +x "$HOOKS_DIR"/*
echo "✅ Hooks已安装"
;;
"update")
echo "更新Git Hooks..."
git pull origin main
chmod +x "$HOOKS_DIR"/*
echo "✅ Hooks已更新"
;;
"list")
echo "可用的Git Hooks:"
ls -la "$HOOKS_DIR/"
;;
"disable")
if [ -z "$2" ]; then
echo "用法: $0 disable <hook-name>"
exit 1
fi
HOOK_FILE="$HOOKS_DIR/$2"
if [ -f "$HOOK_FILE" ]; then
mv "$HOOK_FILE" "$HOOK_FILE.disabled"
echo "✅ Hook已禁用: $2"
else
echo "❌ Hook不存在: $2"
fi
;;
"enable")
if [ -z "$2" ]; then
echo "用法: $0 enable <hook-name>"
exit 1
fi
HOOK_FILE="$HOOKS_DIR/$2.disabled"
if [ -f "$HOOK_FILE" ]; then
mv "$HOOK_FILE" "$HOOKS_DIR/$2"
chmod +x "$HOOKS_DIR/$2"
echo "✅ Hook已启用: $2"
else
echo "❌ 禁用的Hook不存在: $2"
fi
;;
"test")
if [ -z "$2" ]; then
echo "用法: $0 test <hook-name>"
exit 1
fi
HOOK_FILE="$HOOKS_DIR/$2"
if [ -f "$HOOK_FILE" ]; then
echo "测试Hook: $2"
TEMP_DIR=$(mktemp -d)
export GIT_DIR="$PWD/.git"
export GIT_WORK_TREE="$PWD"
"$HOOK_FILE"
rm -rf "$TEMP_DIR"
else
echo "❌ Hook不存在: $2"
fi
;;
"add")
if [ -z "$2" ]; then
echo "用法: $0 add <hook-name>"
echo "可用模板: pre-commit, commit-msg, pre-push, post-commit"
exit 1
fi
echo "创建新的Hook: $2"
cat > "$HOOKS_DIR/$2" << 'EOF'
#!/bin/bash
echo "🪝 自定义Hook: $2"
# 在这里添加你的Hook逻辑
EOF
chmod +x "$HOOKS_DIR/$2"
echo "✅ Hook已创建: $2"
;;
*)
echo "Git Hook管理器"
echo "用法: $0 <command>"
echo ""
echo "命令:"
echo " install 安装所有Hooks"
echo " update 更新Hooks"
echo " list 列出所有Hooks"
echo " disable <name> 禁用Hook"
echo " enable <name> 启用Hook"
echo " test <name> 测试Hook"
echo " add <name> 添加新Hook"
;;
esac
🎯 第四章:Git高级操作与问题解决
4.1 复杂场景操作指南
4.1.1 历史重写与清理
bash
#!/bin/bash
# git-history-rewrite.sh - 安全的历史重写工具
echo "🕰️ Git历史重写工具"
echo "================="
if [ -z "$1" ]; then
echo "选择操作:"
echo "1. 修改最近N次提交的作者信息"
echo "2. 从历史中删除文件"
echo "3. 分割大提交"
echo "4. 合并小提交"
echo "5. 重新排序提交"
echo "6. 修改提交信息"
read -p "选择 (1-6): " choice
else
choice=$1
fi
case $choice in
1)
# 修改作者信息
read -p "修改最近几次提交? " count
read -p "新的作者姓名: " name
read -p "新的作者邮箱: " email
git rebase -i HEAD~$count \
--exec "git commit --amend --author='$name <$email>' --no-edit"
;;
2)
# 从历史中删除文件
read -p "要删除的文件路径: " filepath
if [ ! -f "$filepath" ] && [ ! -d "$filepath" ]; then
echo "❌ 文件不存在: $filepath"
exit 1
fi
echo "⚠️ 警告:这将重写历史,影响所有协作者"
read -p "确认删除? (y/N): " confirm
if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch '$filepath'" \
--prune-empty --tag-name-filter cat -- --all
# 清理空间
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now --aggressive
fi
;;
3)
# 分割大提交
read -p "要分割的提交哈希: " commit_hash
git rebase -i ${commit_hash}^
# 在编辑器中,将该提交改为 'edit'
# 然后:
# git reset HEAD^
# git add -p # 交互式添加部分更改
# git commit -m "第一部分"
# git add -p # 继续添加
# git commit -m "第二部分"
# git rebase --continue
;;
4)
# 合并小提交
read -p "要合并的提交数量: " count
git rebase -i HEAD~$count
# 在编辑器中,将除第一个外的提交改为 'squash' 或 'fixup'
;;
5)
# 重新排序提交
read -p "要重新排序的提交数量: " count
git rebase -i HEAD~$count
# 在编辑器中,拖动行来重新排序提交
;;
6)
# 修改提交信息
read -p "要修改的提交哈希: " commit_hash
git rebase -i ${commit_hash}^
# 在编辑器中,将该提交改为 'reword'
;;
*)
echo "无效选择"
;;
esac
echo "✅ 操作完成"
echo ""
echo "📝 下一步:"
echo "如果是共享分支,需要强制推送:"
echo " git push --force-with-lease"
echo ""
echo "⚠️ 注意:历史重写会影响其他协作者,请谨慎操作"
4.1.2 二分查找与问题定位
bash
#!/bin/bash
# git-bisect-expert.sh - 高级二分查找工具
echo "🔍 Git二分查找专家工具"
echo "===================="
case "$1" in
"start")
echo "开始二分查找..."
read -p "已知的好提交哈希: " good_commit
read -p "已知的坏提交哈希 (默认HEAD): " bad_commit
bad_commit=${bad_commit:-HEAD}
git bisect start
git bisect bad "$bad_commit"
git bisect good "$good_commit"
echo "✅ 二分查找已启动"
echo ""
echo "使用以下命令进行测试:"
echo " git bisect good # 当前提交是好的"
echo " git bisect bad # 当前提交是坏的"
echo " git bisect skip # 跳过当前提交"
echo " git bisect reset # 重置二分查找"
;;
"automate")
echo "自动化二分查找..."
read -p "测试脚本路径: " test_script
if [ ! -f "$test_script" ]; then
echo "❌ 测试脚本不存在: $test_script"
exit 1
fi
read -p "已知的好提交哈希: " good_commit
read -p "已知的坏提交哈希 (默认HEAD): " bad_commit
bad_commit=${bad_commit:-HEAD}
git bisect start
git bisect bad "$bad_commit"
git bisect good "$good_commit"
# 自动化运行
git bisect run "$test_script"
echo "✅ 自动化二分查找完成"
echo "第一个坏提交是: $(git bisect view --format=%H)"
;;
"visual")
echo "可视化二分查找..."
# 需要安装git-bisect-visual
if command -v git-bisect-visual &> /dev/null; then
git bisect visual
else
echo "安装git-bisect-visual:"
echo " pip install git-bisect-visual"
fi
;;
"log")
echo "二分查找日志:"
git bisect log
;;
"replay")
echo "重放二分查找日志..."
if [ -f ".git/BISECT_LOG" ]; then
git bisect replay .git/BISECT_LOG
else
echo "❌ 找不到二分查找日志"
fi
;;
*)
echo "用法: $0 <command>"
echo ""
echo "命令:"
echo " start 开始新的二分查找"
echo " automate 自动化二分查找"
echo " visual 可视化二分查找"
echo " log 查看二分查找日志"
echo " replay 重放二分查找"
echo ""
echo "🌰 示例:"
echo " 查找引入bug的提交:"
echo " $0 start"
echo " git bisect good v1.0.0"
echo " git bisect bad HEAD"
echo ""
echo " 自动化测试:"
echo " $0 automate ./test-bug.sh"
;;
esac
4.2 Git疑难问题解决手册
bash
#!/bin/bash
# git-troubleshooter.sh - Git疑难问题解决专家
echo "🔧 Git疑难问题解决工具"
echo "===================="
case "$1" in
"detached")
echo "问题: 处于分离头指针状态"
echo "解决方案:"
echo "1. 创建新分支保存更改:"
echo " git branch temp-branch"
echo "2. 切换回主分支:"
echo " git checkout main"
echo "3. 合并更改:"
echo " git merge temp-branch"
echo "4. 删除临时分支:"
echo " git branch -d temp-branch"
;;
"merge-conflict")
echo "问题: 合并冲突无法解决"
echo "解决方案:"
echo "1. 查看冲突文件:"
echo " git status"
echo "2. 使用合并工具:"
echo " git mergetool"
echo "3. 手动解决冲突后标记:"
echo " git add <file>"
echo "4. 完成合并:"
echo " git commit"
echo ""
echo "紧急方案(丢弃本地/远程更改):"
echo " # 保留远程版本"
echo " git checkout --theirs <file>"
echo " # 保留本地版本"
echo " git checkout --ours <file>"
;;
"push-rejected")
echo "问题: 推送被拒绝 (non-fast-forward)"
echo "解决方案:"
echo "1. 拉取并重新基于远程分支:"
echo " git pull --rebase origin main"
echo "2. 或者合并远程更改:"
echo " git pull origin main"
echo "3. 强制推送(谨慎使用):"
echo " git push --force-with-lease"
echo ""
echo "预防措施:"
echo " git config --global pull.rebase true"
;;
"lost-commits")
echo "问题: 提交丢失或误删"
echo "解决方案:"
echo "1. 查找丢失的提交:"
echo " git reflog"
echo "2. 恢复提交:"
echo " git cherry-pick <commit-hash>"
echo "3. 或者重置到该提交:"
echo " git reset --hard <commit-hash>"
echo ""
echo "数据恢复工具:"
echo " git fsck --lost-found"
;;
"slow-operations")
echo "问题: Git操作缓慢"
echo "解决方案:"
echo "1. 启用文件系统缓存:"
echo " git config --global core.fscache true"
echo "2. 启用预加载索引:"
echo " git config --global core.preloadindex true"
echo "3. 定期清理:"
echo " git gc --aggressive"
echo "4. 检查大文件:"
echo " git count-objects -vH"
;;
"autocrlf")
echo "问题: 换行符问题 (CRLF/LF)"
echo "解决方案:"
echo "1. Windows设置:"
echo " git config --global core.autocrlf true"
echo "2. macOS/Linux设置:"
echo " git config --global core.autocrlf input"
echo "3. 统一仓库设置:"
echo " echo '* text=auto' > .gitattributes"
echo "4. 修复现有文件:"
echo " git add --renormalize ."
;;
"ssh-issues")
echo "问题: SSH连接问题"
echo "解决方案:"
echo "1. 测试连接:"
echo " ssh -T git@github.com"
echo "2. 检查SSH密钥:"
echo " ssh-add -l"
echo "3. 重新添加密钥:"
echo " ssh-add ~/.ssh/id_ed25519"
echo "4. 调试模式:"
echo " ssh -vT git@github.com"
;;
*)
echo "常见Git问题解决指南"
echo ""
echo "用法: $0 <problem>"
echo ""
echo "可用问题:"
echo " detached 分离头指针状态"
echo " merge-conflict 合并冲突"
echo " push-rejected 推送被拒绝"
echo " lost-commits 提交丢失"
echo " slow-operations 操作缓慢"
echo " autocrlf 换行符问题"
echo " ssh-issues SSH连接问题"
echo ""
echo "更多帮助:"
echo " git <command> --help"
echo " man git-<command>"
echo " https://git-scm.com/docs"
;;
esac
🚀 第五章:Git生态系统与扩展工具
5.1 必备Git扩展工具
markdown
# 🛠️ Git扩展工具生态系统
## 命令行增强
### delta
```bash
# 更好的diff查看器
brew install git-delta # macOS
# 配置在.gitconfig:
[core]
pager = delta
[delta]
features = side-by-side line-numbers
syntax-theme = GitHub
tig
bash
# 终端Git浏览器
brew install tig
# 使用: tig, tig status, tig blame
lazygit
bash
# 终端Git GUI
brew install lazygit
# 功能丰富的终端界面
可视化工具
GitKraken
- 跨平台Git GUI
- 高级可视化合并工具
- 团队协作功能
Sourcetree
- 免费的Git GUI
- 与Jira/Bitbucket集成
- 强大的提交历史浏览
GitLens (VSCode扩展)
- 代码行历史
- 提交详情内联显示
- 强大的搜索功能
代码质量工具
pre-commit
bash
# Git钩子框架
pip install pre-commit
# .pre-commit-config.yaml:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
commitlint
bash
# 提交信息规范检查
npm install --save-dev @commitlint/config-conventional @commitlint/cli
# .commitlintrc.js:
module.exports = {
extends: ['@commitlint/config-conventional']
}
性能工具
Scalar
bash
# 微软的大型仓库优化工具
# 下载: https://github.com/microsoft/scalar
scalar clone https://github.com/large/repo.git
# 自动配置: 稀疏检出、对象池等
VFS for Git (GVFS)
- 超大型仓库解决方案
- 按需获取文件
- 微软开发,用于Windows源码
安全工具
git-secrets
bash
# AWS开发的敏感信息检查
git secrets --install
git secrets --register-aws
# 扫描提交中的密钥
truffleHog
bash
# 查找提交历史中的敏感信息
pip install trufflehog
trufflehog --regex --entropy=False https://github.com/user/repo.git
工作流工具
git-flow
bash
# Git Flow实现
brew install git-flow
git flow init
gh (GitHub CLI)
bash
# GitHub命令行工具
brew install gh
gh pr create
gh issue list
gh repo view
GitLab CLI (glab)
bash
# GitLab命令行工具
brew install glab
glab mr create
glab pipeline status
开发工具集成
Git Graph (VSCode)
- 可视化提交历史
- 分支操作界面
- 合并冲突解决
Git History (VSCode)
- 详细的文件历史
- 分支比较
- 提交详情
Git Blame (VSCode)
-
交互式代码追溯
-
查看每行修改历史
-
快速跳转到提交
5.2 自定义Git命令开发
bash#!/bin/bash # git-custom-commands.sh - 自定义Git命令开发模板 echo "🚀 Git自定义命令开发" echo "=================" CUSTOM_DIR="$HOME/.git-custom-commands" mkdir -p "$CUSTOM_DIR" # 添加到PATH if ! echo "$PATH" | grep -q "$CUSTOM_DIR"; then echo "export PATH=\"\$PATH:$CUSTOM_DIR\"" >> ~/.zshrc echo "export PATH=\"\$PATH:$CUSTOM_DIR\"" >> ~/.bashrc fi # 1. git-sync-all - 同步所有远程分支 cat > "$CUSTOM_DIR/git-sync-all" << 'EOF' #!/bin/bash # 同步所有远程分支 echo "🔄 同步所有远程分支..." # 获取所有远程分支 REMOTE_BRANCHES=$(git branch -r | grep -v '\->' | sed 's/origin\///') for branch in $REMOTE_BRANCHES; do echo "处理分支: $branch" # 检查本地是否存在 if git show-ref --verify --quiet refs/heads/"$branch"; then # 本地存在,拉取更新 git checkout "$branch" git pull origin "$branch" else # 本地不存在,创建并跟踪 git checkout -b "$branch" origin/"$branch" fi done # 切回原始分支 git checkout @{-1} echo "✅ 所有分支同步完成" EOF # 2. git-cleanup - 智能清理 cat > "$CUSTOM_DIR/git-cleanup" << 'EOF' #!/bin/bash # 智能清理Git仓库 echo "🧹 Git仓库清理..." # 1. 删除已合并的分支 echo "删除已合并到main的分支..." git branch --merged main | grep -v "main" | xargs -r git branch -d # 2. 删除已合并的远程分支引用 echo "清理远程分支引用..." git fetch --prune # 3. 清理reflog echo "清理旧的reflog..." git reflog expire --expire=30.days --all # 4. 垃圾回收 echo "运行垃圾回收..." git gc --auto # 5. 清理stash echo "清理旧的stash..." STASH_COUNT=$(git stash list | wc -l) if [ $STASH_COUNT -gt 5 ]; then echo "有 $STASH_COUNT 个stash,建议清理" git stash list fi echo "✅ 清理完成" EOF # 3. git-branch-report - 分支报告 cat > "$CUSTOM_DIR/git-branch-report" << 'EOF' #!/bin/bash # 生成分支状态报告 echo "📊 Git分支状态报告" echo "=================" echo "生成时间: $(date)" echo "" # 活跃分支(最近30天有提交) echo "🟢 活跃分支(最近30天):" git for-each-ref --format='%(refname:short) %(committerdate:relative)' \ --sort=-committerdate refs/heads/ | \ while read branch date; do if echo "$date" | grep -q "day\|week"; then echo " $branch - $date" fi done echo "" echo "🟡 陈旧分支(超过30天):" git for-each-ref --format='%(refname:short) %(committerdate:relative)' \ --sort=-committerdate refs/heads/ | \ while read branch date; do if echo "$date" | grep -q "month\|year"; then commits=$(git log --oneline origin/main..$branch 2>/dev/null | wc -l) echo " $branch - $date (有 $commits 个提交未合并)" fi done echo "" echo "🔴 已合并可删除分支:" git branch --merged main | grep -v "main" | \ while read branch; do last_commit=$(git log -1 --format="%cr" "$branch") echo " $branch - 最后提交: $last_commit" done echo "" echo "📈 统计:" echo " 总分支数: $(git branch | wc -l | tr -d ' ')" echo " 活跃分支: $(git for-each-ref --format='%(refname:short)' refs/heads/ | \ while read branch; do if [ $(git log --since="30 days ago" $branch | wc -l) -gt 0 ]; then echo "$branch" fi done | wc -l)" echo " 远程分支: $(git branch -r | wc -l | tr -d ' ')" EOF # 4. git-search-all - 全局搜索 cat > "$CUSTOM_DIR/git-search-all" << 'EOF' #!/bin/bash # 在所有分支中搜索 if [ -z "$1" ]; then echo "用法: git search-all <搜索内容>" exit 1 fi SEARCH_TERM="$1" echo "🔍 在所有分支中搜索: $SEARCH_TERM" echo "==============================" # 获取所有分支 BRANCHES=$(git branch -a | sed 's/^\*\?\s*//' | sed 's/remotes\///') for branch in $BRANCHES; do # 跳过HEAD和重复的远程分支 if [[ "$branch" == "HEAD" ]] || [[ "$branch" == *"->"* ]]; then continue fi # 搜索提交信息 RESULTS=$(git log --oneline --grep="$SEARCH_TERM" "$branch" 2>/dev/null) if [ ! -z "$RESULTS" ]; then echo "" echo "📁 分支: $branch" echo "$RESULTS" fi # 搜索文件内容 FILES=$(git grep -l "$SEARCH_TERM" "$branch" 2>/dev/null) if [ ! -z "$FILES" ]; then echo "📄 包含的文件:" echo "$FILES" | sed 's/^/ /' fi done EOF # 设置执行权限 chmod +x "$CUSTOM_DIR"/* echo "✅ 自定义Git命令已安装" echo "" echo "可用命令:" echo " git sync-all 同步所有远程分支" echo " git cleanup 智能清理仓库" echo " git branch-report 生成分支报告" echo " git search-all 全局搜索" echo "" echo "添加更多命令到: $CUSTOM_DIR/"
📊 第六章:Git专业工作流模板
6.1 企业级Git工作流配置包
yaml
# .gitworkflow/config.yaml - 工作流配置文件
version: 1.0
workflow:
name: "企业级Git工作流"
description: "标准化的开发、测试、发布流程"
branches:
main:
protection:
required_status_checks:
strict: true
contexts:
- "ci/build"
- "ci/test"
- "security/scan"
required_pull_request_reviews:
required_approving_review_count: 2
dismiss_stale_reviews: true
restrictions:
users: []
teams:
- "maintainers"
- "devops"
develop:
protection:
required_status_checks:
contexts:
- "ci/test"
required_pull_request_reviews:
required_approving_review_count: 1
patterns:
feature: "feature/*"
bugfix: "bugfix/*"
hotfix: "hotfix/*"
release: "release/*"
pull_request:
template: ".github/PULL_REQUEST_TEMPLATE.md"
auto_merge: true
delete_branch_on_merge: true
commit:
convention: "conventional"
types:
- "feat"
- "fix"
- "docs"
- "style"
- "refactor"
- "test"
- "chore"
- "perf"
- "ci"
- "build"
- "revert"
ci_cd:
stages:
- name: "quality"
jobs: ["lint", "test", "security"]
- name: "build"
jobs: ["compile", "package"]
- name: "deploy"
environments:
- name: "staging"
auto_deploy: true
- name: "production"
manual_approval: true
notifications:
slack:
channel: "#engineering"
events:
- "pull_request.opened"
- "pull_request.merged"
- "deployment.started"
- "deployment.succeeded"
- "deployment.failed"
6.2 一键部署脚本
bash
#!/bin/bash
# setup-git-workflow.sh - 一键部署完整Git工作流
echo "🚀 Git工作流一键部署"
echo "================="
# 检查必要工具
command -v pre-commit >/dev/null 2>&1 || {
echo "安装 pre-commit..."
pip install pre-commit
}
command -v commitlint >/dev/null 2>&1 || {
echo "安装 commitlint..."
npm install -g @commitlint/cli @commitlint/config-conventional
}
# 1. 创建目录结构
echo "1. 创建目录结构..."
mkdir -p .github/{workflows,ISSUE_TEMPLATE}
mkdir -p .githooks
mkdir -p .changelogs/unreleased
# 2. 配置pre-commit
echo "2. 配置pre-commit..."
cat > .pre-commit-config.yaml << 'EOF'
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
args: ['--maxkb=5120']
- id: check-merge-conflict
- id: detect-private-key
- repo: https://github.com/commitizen-tools/commitizen
rev: v2.39.1
hooks:
- id: commitizen
stages: [commit-msg]
- repo: https://github.com/jorisroovers/gitlint
rev: v0.19.1
hooks:
- id: gitlint
- repo: local
hooks:
- id: eslint
name: ESLint
entry: npm run lint
language: system
pass_filenames: false
stages: [commit]
- id: tests
name: Tests
entry: npm test
language: system
pass_filenames: false
stages: [commit]
EOF
# 3. 配置commitlint
echo "3. 配置commitlint..."
cat > .commitlintrc.js << 'EOF'
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat',
'fix',
'docs',
'style',
'refactor',
'test',
'chore',
'perf',
'ci',
'build',
'revert'
]
],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'scope-case': [2, 'always', 'lower-case'],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'header-max-length': [2, 'always', 72]
}
}
EOF
# 4. 配置GitHub Actions
echo "4. 配置GitHub Actions..."
cat > .github/workflows/ci.yml << 'EOF'
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Test
run: npm test
- name: Coverage
run: npm run test:coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
- name: CodeQL Analysis
uses: github/codeql-action/analyze@v2
build:
needs: [quality, security]
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v3
- name: Build
run: npm run build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: build-output
path: dist/
EOF
# 5. 配置Issue和PR模板
echo "5. 配置模板..."
cat > .github/ISSUE_TEMPLATE/bug_report.md << 'EOF'
---
name: Bug报告
about: 报告一个bug
title: '[BUG] '
labels: bug
assignees: ''
---
## 问题描述
清晰简洁地描述bug是什么。
## 复现步骤
1. 前往 '...'
2. 点击 '....'
3. 滚动到 '....'
4. 看到错误
## 预期行为
清晰简洁地描述你期望发生什么。
## 实际行为
清晰简洁地描述实际发生了什么。
## 屏幕截图
如果适用,添加屏幕截图以帮助解释您的问题。
## 环境信息
- 操作系统: [例如 iOS]
- 浏览器: [例如 chrome, safari]
- 版本: [例如 22]
## 其他上下文
在此处添加有关该问题的任何其他上下文。
EOF
cat > .github/PULL_REQUEST_TEMPLATE.md << 'EOF'
## PR类型
- [ ] 🚀 新功能
- [ ] 🐛 Bug修复
- [ ] 📝 文档更新
- [ ] 🎨 代码风格
- [ ] 🔧 重构
- [ ] ✅ 测试
- [ ] 🔨 其他
## 关联Issue
Closes #
## 变更描述
请详细描述本次PR的变更内容:
## 测试验证
- [ ] 本地单元测试通过
- [ ] 集成测试通过
- [ ] UI测试通过
- [ ] 性能测试通过
## 截图/录屏
<!-- 如果是UI变更,请提供截图 -->
## 检查清单
- [ ] 代码符合项目规范
- [ ] 已更新相关文档
- [ ] 已添加或更新测试用例
- [ ] 所有CI检查通过
## 其他备注
<!-- 需要特别说明的事项 -->
EOF
# 6. 配置Git Hook路径
echo "6. 配置Git Hook..."
git config core.hooksPath .githooks
# 7. 创建初始文件
echo "7. 创建初始文件..."
cat > .gitattributes << 'EOF'
# 自动检测文本文件并标准化行尾
* text=auto
# 明确声明文本文件
*.js text
*.ts text
*.jsx text
*.tsx text
*.json text
*.md text
*.yml text
*.yaml text
# 声明不应被修改的文件
*.jpg -text
*.png -text
*.gif -text
EOF
cat > .editorconfig << 'EOF'
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{json,yml,yaml}]
indent_size = 2
[*.py]
indent_size = 4
EOF
# 8. 安装和初始化
echo "8. 安装和初始化..."
pre-commit install --hook-type pre-commit
pre-commit install --hook-type commit-msg
# 配置husky(如果使用npm)
if [ -f "package.json" ]; then
npx husky install
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
fi
echo "✅ Git工作流部署完成"
echo ""
echo "🎉 已安装组件:"
echo " - pre-commit钩子"
echo " - commitlint配置"
echo " - GitHub Actions CI/CD"
echo " - Issue和PR模板"
echo " - Git属性配置"
echo " - EditorConfig"
echo ""
echo "📝 下一步:"
echo " 1. 更新 package.json 中的脚本"
echo " 2. 配置 secrets (SNYK_TOKEN, CODECOV_TOKEN)"
echo " 3. 运行: pre-commit run --all-files"
echo " 4. 提交初始配置"
🎯 总结:成为Git大师的路径
关键收获回顾
- 理解Git本质:Git不只是命令集合,而是数据存储和协作的理念
- 掌握内部原理:理解对象模型、引用系统是成为专家的基础
- 优化性能:针对不同场景选择合适的克隆、存储、优化策略
- 自定义工作流:根据团队需求设计最适合的Git工作流
- 集成生态系统:Git与CI/CD、代码质量、安全工具深度集成
立即行动清单
bash
# 🚀 本周可以开始的高级实践
# 1. 探索Git内部
git cat-file -p HEAD
git ls-tree -r HEAD
git rev-parse HEAD
# 2. 配置专业环境
cp ~/.gitconfig ~/.gitconfig.backup
# 应用本章的专业配置模板
# 3. 设置企业级Hook
./setup-enterprise-hooks.sh
# 4. 分析仓库性能
git count-objects -vH
git gc --aggressive
# 5. 学习一个新命令
man git-worktree # 多工作目录管理
man git-bundle # 打包传输
man git-archive # 创建归档
Git大师的思维模式
"A Git master doesn't just use Git, they understand how Git thinks."
- 版本控制哲学:每次提交都是可追溯的决策记录
- 协作优先:设计便于团队协作的工作流
- 自动化思维:能自动化的绝不手动操作
- 性能意识:始终考虑大型仓库的可扩展性
- 安全第一:保护代码历史和数据安全
持续学习资源
markdown
# 📚 Git深度学习资源
## 官方资源
- [Pro Git Book](https://git-scm.com/book) - 必读经典
- [Git Internals](https://git-scm.com/docs) - 官方文档
- [Git Community](https://git-scm.com/community) - 社区资源
## 视频课程
- [Advanced Git Techniques](https://www.pluralsight.com) - Pluralsight
- [Git Deep Dive](https://frontendmasters.com) - Frontend Masters
- [Git for Professionals](https://www.udemy.com) - Udemy
## 开源项目
- [git](https://github.com/git/git) - Git源码
- [libgit2](https://github.com/libgit2/libgit2) - Git库实现
- [GitHub Training](https://github.com/github/training-kit) - 培训材料
## 社区
- [Stack Overflow Git](https://stackoverflow.com/questions/tagged/git)
- [GitHub Community](https://github.com/community)
- [GitLab Forum](https://forum.gitlab.com)
## 工具更新
- 关注Git、GitHub、GitLab的发布说明
- 订阅Git Weekly等新闻通讯
- 参加本地技术分享会
🌟 最后的建议
- 从今天开始:选择一个高级功能深入实践
- 分享知识:教别人是巩固学习的最好方式
- 保持好奇:Git生态系统在不断发展
- 参与社区:贡献自己的力量
- 享受过程:成为Git大师是一段有趣的旅程
记住:Git不仅是工具,更是软件开发文化的体现。掌握Git,就是掌握现代软件开发的协作艺术。
开始你的Git大师之旅吧! ⚡
系列完结 🎉
通过这三篇完整教程,你已经从Git新手成长为可以设计企业级Git工作流的专家。记住,真正的专家不是知道所有命令的人,而是知道在正确的时间使用正确工具解决问题的人。
保持学习,保持分享,保持创造!