Git工作流最佳实践与高级技巧

开发工具分享

Git工作流最佳实践与高级技巧

Git是目前最流行的分布式版本控制系统。本文将分享Git的最佳实践和高级使用技巧。

Git基础配置

1. 全局配置

# 配置用户信息
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# 配置默认编辑器
git config --global core.editor "code --wait"

# 配置默认分支名
git config --global init.defaultBranch main

# 配置别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

# 配置换行符
git config --global core.autocrlf input  # Linux/Mac
git config --global core.autocrlf true   # Windows

# 配置合并工具
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd "code --wait $MERGED"

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

2. 配置文件示例

# ~/.gitconfig
[user]
    name = Your Name
    email = your.email@example.com
[core]
    editor = code --wait
    autocrlf = input
    whitespace = trailing-space,space-before-tab
[init]
    defaultBranch = main
[alias]
    st = status -sb
    co = checkout
    br = branch
    ci = commit
    lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
    unstage = reset HEAD --
    last = log -1 HEAD
    visual = !gitk
[push]
    default = simple
[pull]
    rebase = true
[fetch]
    prune = true
[diff]
    tool = vscode
[difftool "vscode"]
    cmd = code --wait --diff $LOCAL $REMOTE
[merge]
    tool = vscode
    conflictstyle = diff3
[mergetool "vscode"]
    cmd = code --wait $MERGED
[color]
    ui = auto
[commit]
    template = ~/.gitmessage

分支策略

1. Git Flow

分支结构:
main        生产分支
├── develop 开发分支
│   ├── feature/user-auth      功能分支
│   ├── feature/payment        功能分支
│   └── hotfix/security-fix    热修复分支
├── release/v1.0.0             发布分支
└── hotfix/critical-bug        热修复分支

工作流程:
1. 从main创建develop分支
2. 从develop创建feature分支开发功能
3. 功能完成后合并回develop
4. 发布时从develop创建release分支
5. release测试通过后合并到main和develop
6. 生产环境发现问题,从main创建hotfix分支
7. 修复完成后合并到main和develop

2. GitHub Flow

简化流程:
1. 从main创建feature分支
2. 在feature分支上开发
3. 提交Pull Request
4. Code Review
5. 合并到main
6. 自动部署

适用场景:
- 持续部署
- 小型团队
- Web应用

3. GitLab Flow

带环境分支:
main        开发分支
├── staging 预发布分支
└── production 生产分支

带发布分支:
main
├── release/v1.0
├── release/v1.1
└── release/v2.0

提交规范

1. Conventional Commits

格式:<type>(<scope>): <subject>

类型(type):
- feat: 新功能
- fix: 修复
- docs: 文档
- style: 格式
- refactor: 重构
- perf: 性能优化
- test: 测试
- chore: 构建/工具

示例:
feat(user): add login functionality
fix(api): resolve null pointer exception
docs(readme): update installation guide
refactor(auth): simplify token validation

2. 提交信息模板

# 创建提交模板
cat > ~/.gitmessage << 'EOF'
# <type>(<scope>): <subject>
# 
# <body>
#
# <footer>
#
# Type可以是:
#   feat: 新功能
#   fix: 修复
#   docs: 文档
#   style: 格式
#   refactor: 重构
#   perf: 性能
#   test: 测试
#   chore: 构建
#
# Footer可以包含:
#   BREAKING CHANGE: 破坏性变更
#   Closes #123, #456: 关闭的Issue
EOF

# 配置使用模板
git config --global commit.template ~/.gitmessage

3. 提交最佳实践

# 1. 原子性提交
# 每个提交只做一件事
git add src/auth/login.js
git commit -m "feat(auth): implement JWT token validation"

# 2. 有意义的提交信息
# 不好的例子
git commit -m "fix bug"
git commit -m "update"

# 好的例子
git commit -m "fix(auth): resolve session timeout issue on token refresh"
git commit -m "docs(api): add OpenAPI specification for user endpoints"

# 3. 频繁提交
git add src/utils/validator.js
git commit -m "feat(utils): add email validation helper"

git add src/utils/formatter.js
git commit -m "feat(utils): add date formatting helper"

# 4. 提交前检查
git diff --cached  # 查看暂存区变更
npm test           # 运行测试
npm run lint       # 代码检查

高级操作

1. 交互式暂存

# 交互式添加
git add -i

# 选择补丁模式
git add -p

# 操作选项:
# y - 暂存此块
# n - 不暂存此块
# s - 分割成更小块
# e - 手动编辑
# ? - 帮助

2. 变基操作

# 交互式变基
git rebase -i HEAD~5

# 常用命令:
# p, pick - 使用提交
# r, reword - 修改提交信息
# e, edit - 修改提交
# s, squash - 合并到上一个提交
# f, fixup - 类似squash,但丢弃提交信息
# d, drop - 删除提交

# 变基到main分支
git checkout feature
git rebase main

# 解决冲突后继续
git rebase --continue

# 跳过当前提交
git rebase --skip

# 中止变基
git rebase --abort

3. 储藏操作

# 储藏当前更改
git stash

# 储藏并添加说明
git stash push -m "WIP: user authentication"

# 查看储藏列表
git stash list

# 应用最近的储藏
git stash pop

# 应用指定储藏
git stash apply stash@{2}

# 删除储藏
git stash drop stash@{0}

# 清空所有储藏
git stash clear

# 从储藏创建分支
git stash branch feature-branch stash@{0}

4. 拣选提交

# 拣选单个提交
git cherry-pick abc123

# 拣选多个提交
git cherry-pick abc123 def456

# 拣选范围
git cherry-pick abc123^..def456

# 拣选但不提交
git cherry-pick -n abc123

# 处理冲突后继续
git cherry-pick --continue

# 中止拣选
git cherry-pick --abort

冲突解决

1. 查看冲突

# 查看冲突文件
git status

# 查看冲突详情
git diff

# 查看合并状态
git merge --abort

2. 解决策略

# 使用我们的版本
git checkout --ours path/to/file

# 使用他们的版本
git checkout --theirs path/to/file

# 标记为已解决
git add path/to/file

# 完成合并
git commit

3. 预防冲突

# 频繁拉取更新
git pull --rebase

# 先更新再推送
git pull origin main
git push origin feature

# 使用rebase保持线性历史
git config pull.rebase true

历史管理

1. 修改历史

# 修改最后一次提交
git commit --amend

# 修改提交信息
git commit --amend -m "新的提交信息"

# 添加遗漏的文件
git add forgotten-file
git commit --amend --no-edit

# 修改历史提交(谨慎使用)
git rebase -i HEAD~3

2. 撤销操作

# 撤销工作区修改
git checkout -- file.txt

# 撤销暂存区文件
git reset HEAD file.txt

# 软重置(保留工作区)
git reset --soft HEAD~1

# 混合重置(保留工作区,清空暂存区)
git reset --mixed HEAD~1

# 硬重置(丢弃所有修改)
git reset --hard HEAD~1

# 查看所有操作记录
git reflog

# 恢复到指定状态
git reset --hard abc123

3. 清理仓库

# 清理未跟踪文件
git clean -n   # 预览
git clean -f   # 强制删除
git clean -fd  # 包含目录
git clean -fx  # 包含忽略的文件

# 垃圾回收
git gc

# 完全清理
git gc --aggressive --prune=now

子模块管理

1. 添加子模块

# 添加子模块
git submodule add https://github.com/example/lib.git libs/lib

# 初始化子模块
git submodule init

# 更新子模块
git submodule update

# 克隆包含子模块的项目
git clone --recursive https://github.com/example/project.git

2. 子模块操作

# 更新所有子模块
git submodule update --remote

# 在子模块中执行命令
git submodule foreach 'git checkout main'

# 删除子模块
# 1. 删除子模块目录
rm -rf libs/lib
# 2. 删除.gitmodules中的相关配置
# 3. 删除.git/config中的相关配置
# 4. 删除.git/modules中的相关目录
git rm --cached libs/lib

大文件管理

1. Git LFS

# 安装Git LFS
git lfs install

# 追踪大文件
git lfs track "*.psd"
git lfs track "*.zip"
git lfs track "videos/*"

# 查看追踪的文件
git lfs track

# 查看LFS文件
git lfs ls-files

# 迁移到LFS
git lfs migrate import --include="*.zip"

2. 文件过滤

# .gitattributes
*.zip filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text

工作流脚本

1. 自动提交脚本

#!/bin/bash
# git-auto-commit.sh

# 检查是否有变更
if git diff-index --quiet HEAD --; then
    echo "No changes to commit"
    exit 0
fi

# 获取当前分支
BRANCH=$(git branch --show-current)

# 添加所有变更
git add -A

# 生成提交信息
MESSAGE="auto: update on $(date '+%Y-%m-%d %H:%M:%S')"

# 提交
git commit -m "$MESSAGE"

# 推送
git push origin $BRANCH

echo "Committed and pushed to $BRANCH"

2. 清理分支脚本

#!/bin/bash
# git-clean-branches.sh

# 删除已合并的本地分支
git branch --merged | grep -v "\\*" | grep -v main | grep -v master | xargs -n 1 git branch -d

# 删除已合并的远程分支
git remote prune origin

# 删除远程已删除的本地追踪分支
git fetch --prune

echo "Cleanup completed"

团队协作

1. Code Review流程

# 创建功能分支
git checkout -b feature/new-feature

# 开发并提交
git add .
git commit -m "feat: implement new feature"

# 推送到远程
git push -u origin feature/new-feature

# 创建Pull Request(在GitHub/GitLab上操作)

# 根据Review修改
git add .
git commit --amend --no-edit
git push --force-with-lease

# 合并后清理
git checkout main
git pull origin main
git branch -d feature/new-feature
git push origin --delete feature/new-feature

2. 发布管理

# 创建发布分支
git checkout -b release/v1.0.0 develop

# 版本号更新
# 修改version文件

git add .
git commit -m "chore(release): bump version to 1.0.0"

# 合并到main
git checkout main
git merge --no-ff release/v1.0.0
git tag -a v1.0.0 -m "Release version 1.0.0"

# 合并回develop
git checkout develop
git merge --no-ff release/v1.0.0

# 删除发布分支
git branch -d release/v1.0.0

总结

Git最佳实践的关键点:

  1. 规范配置:统一的用户信息和别名配置
  2. 分支策略:选择合适的分支模型
  3. 提交规范:使用规范的提交信息格式
  4. 原子提交:每个提交只做一件事
  5. 频繁提交:小步快跑,频繁提交
  6. 历史管理:保持清晰的历史记录
  7. 团队协作:良好的Code Review流程

通过遵循这些最佳实践,可以提高团队协作效率,保持代码库的整洁和可维护性。