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最佳实践的关键点:
- 规范配置:统一的用户信息和别名配置
- 分支策略:选择合适的分支模型
- 提交规范:使用规范的提交信息格式
- 原子提交:每个提交只做一件事
- 频繁提交:小步快跑,频繁提交
- 历史管理:保持清晰的历史记录
- 团队协作:良好的Code Review流程
通过遵循这些最佳实践,可以提高团队协作效率,保持代码库的整洁和可维护性。