git-workflow

git-workflow

热门

Git 工作流模式,包括分支策略、提交规范、合并与变基、冲突解决以及适合各种规模团队的协作开发最佳实践。

23万Star
3.5万Fork
更新于 2026/7/17
SKILL.md
readonly只读
name
git-workflow
description

Git 工作流模式,包括分支策略、提交规范、合并与变基、冲突解决以及适合各种规模团队的协作开发最佳实践。

Git 工作流模式

Git 版本控制、分支策略和协作开发的最佳实践。

何时使用

  • 为新项目设置 Git 工作流
  • 决定分支策略(GitFlow、主干开发、GitHub Flow)
  • 编写提交信息和 PR 描述
  • 解决合并冲突
  • 管理发布和版本标签
  • 让新团队成员熟悉 Git 实践

分支策略

GitHub Flow(简单,推荐大多数团队使用)

最适合持续部署和中小型团队。

main(受保护,始终可部署)
  │
  ├── feature/user-auth      → PR → 合并到 main
  ├── feature/payment-flow   → PR → 合并到 main
  └── fix/login-bug          → PR → 合并到 main

规则:

  • main 始终可部署
  • main 创建功能分支
  • 准备好审查时打开 Pull Request
  • 审查通过且 CI 通过后,合并到 main
  • 合并后立即部署

主干开发(高速度团队)

最适合拥有强大 CI/CD 和功能开关的团队。

main(主干)
  │
  ├── 短期分支(最多 1-2 天)
  ├── 短期分支
  └── 短期分支

规则:

  • 所有人都提交到 main 或非常短期的分支
  • 功能开关隐藏未完成的工作
  • 合并前必须通过 CI
  • 每天部署多次

GitFlow(复杂,发布周期驱动)

最适合计划发布和企业项目。

main(生产发布)
  │
  └── develop(集成分支)
        │
        ├── feature/user-auth
        ├── feature/payment
        │
        ├── release/1.0.0    → 合并到 main 和 develop
        │
        └── hotfix/critical  → 合并到 main 和 develop

规则:

  • main 只包含生产就绪代码
  • develop 是集成分支
  • 功能分支从 develop 创建,合并回 develop
  • 发布分支从 develop 创建,合并到 maindevelop
  • 热修复分支从 main 创建,合并到 maindevelop

何时使用哪种策略

策略 团队规模 发布频率 最适合
GitHub Flow 任意 持续 SaaS、Web 应用、初创公司
主干开发 5 人以上有经验 每天多次 高速度团队、功能开关
GitFlow 10 人以上 计划发布 企业、受监管行业

提交信息

常规提交格式

<类型>(<范围>): <主题>

[可选正文]

[可选脚注]

类型

类型 用途 示例
feat 新功能 feat(auth): add OAuth2 login
fix 错误修复 fix(api): handle null response in user endpoint
docs 文档 docs(readme): update installation instructions
style 格式调整,无代码变更 style: fix indentation in login component
refactor 代码重构 refactor(db): extract connection pool to module
test 添加/更新测试 test(auth): add unit tests for token validation
chore 维护任务 chore(deps): update dependencies
perf 性能改进 perf(query): add index to users table
ci CI/CD 变更 ci: add PostgreSQL service to test workflow
revert 回滚之前的提交 revert: revert "feat(auth): add OAuth2 login"

好与坏的示例

# 差:模糊,无上下文
git commit -m "fixed stuff"
git commit -m "updates"
git commit -m "WIP"

# 好:清晰、具体、解释原因
git commit -m "fix(api): retry requests on 503 Service Unavailable

外部 API 在高峰时段偶尔返回 503 错误。
添加了指数退避重试逻辑,最多重试 3 次。

Closes #123"

提交信息模板

在仓库根目录创建 .gitmessage

# <类型>(<范围>): <主题>
# # 类型:feat, fix, docs, style, refactor, test, chore, perf, ci, revert
# 范围:api, ui, db, auth 等
# 主题:祈使语气,无句号,最多 50 个字符
#
# [可选正文] - 解释为什么,而不是什么
# [可选脚注] - 破坏性变更,关闭 #issue

启用:git config commit.template .gitmessage

合并 vs 变基

合并(保留历史)

# 创建合并提交
git checkout main
git merge feature/user-auth

# 结果:
# *   合并提交
# |\
# | * 功能分支提交
# |/
# * main 提交

何时使用:

  • 将功能分支合并到 main
  • 希望保留精确历史
  • 多人参与该分支
  • 分支已推送,其他人可能基于它工作

变基(线性历史)

# 将功能分支的提交重写到目标分支之上
git checkout feature/user-auth
git rebase main

# 结果:
# * 功能分支提交(已重写)
# * main 提交

何时使用:

  • 用最新的 main 更新本地功能分支
  • 希望获得线性、干净的历史
  • 分支仅本地存在(未推送)
  • 只有你一个人在该分支上工作

变基工作流

# 用最新的 main 更新功能分支(PR 之前)
git checkout feature/user-auth
git fetch origin
git rebase origin/main

# 修复任何冲突
# 测试仍应通过

# 强制推送(仅当你一个人贡献时)
git push --force-with-lease origin feature/user-auth

何时不要变基

# 永远不要变基以下分支:
- 已推送到共享仓库
- 其他人已基于它工作
- 受保护分支(main, develop)
- 已合并的分支

# 原因:变基会重写历史,破坏其他人的工作

Pull Request 工作流

PR 标题格式

<类型>(<范围>): <描述>

示例:
feat(auth): add SSO support for enterprise users
fix(api): resolve race condition in order processing
docs(api): add OpenAPI specification for v2 endpoints

PR 描述模板

## 做了什么

简要描述此 PR 做了什么。

## 为什么

解释动机和背景。

## 如何实现

值得强调的关键实现细节。

## 测试

- [ ] 单元测试已添加/更新
- [ ] 集成测试已添加/更新
- [ ] 已执行手动测试

## 截图(如适用)

UI 变更的前后截图。

## 检查清单

- [ ] 代码遵循项目风格指南
- [ ] 已完成自我审查
- [ ] 复杂逻辑已添加注释
- [ ] 文档已更新
- [ ] 未引入新警告
- [ ] 测试在本地通过
- [ ] 相关 issue 已链接

Closes #123

代码审查检查清单

审查者:

  • [ ] 代码是否解决了所述问题?
  • [ ] 是否有未处理的边界情况?
  • [ ] 代码是否可读且可维护?
  • [ ] 是否有足够的测试?
  • [ ] 是否存在安全问题?
  • [ ] 提交历史是否干净(必要时已压缩)?

作者:

  • [ ] 在请求审查前已完成自我审查
  • [ ] CI 通过(测试、lint、类型检查)
  • [ ] PR 大小合理(理想情况下 <500 行)
  • [ ] 与单个功能/修复相关
  • [ ] 描述清楚解释了变更

冲突解决

识别冲突

# 合并前检查冲突
git checkout main
git merge feature/user-auth --no-commit --no-ff

# 如果有冲突,Git 会显示:
# CONFLICT (content): Merge conflict in src/auth/login.ts
# Automatic merge failed; fix conflicts and then commit the result.

解决冲突

# 查看冲突文件
git status

# 查看文件中的冲突标记
# <<<<<<< HEAD
# main 的内容
# =======
# 功能分支的内容
# >>>>>>> feature/user-auth

# 选项 1:手动解决
# 编辑文件,删除标记,保留正确内容

# 选项 2:使用合并工具
git mergetool

# 选项 3:接受某一方
git checkout --ours src/auth/login.ts    # 保留 main 版本
git checkout --theirs src/auth/login.ts  # 保留功能分支版本

# 解决后,暂存并提交
git add src/auth/login.ts
git commit

冲突预防策略

# 1. 保持功能分支小而短命
# 2. 频繁变基到 main
git checkout feature/user-auth
git fetch origin
git rebase origin/main

# 3. 与团队沟通涉及共享文件的修改
# 4. 使用功能开关代替长期分支
# 5. 及时审查和合并 PR

分支管理

命名规范

# 功能分支
feature/user-authentication
feature/JIRA-123-payment-integration

# 错误修复
fix/login-redirect-loop
fix/456-null-pointer-exception

# 热修复(生产问题)
hotfix/critical-security-patch
hotfix/database-connection-leak

# 发布
release/1.2.0
release/2024-01-hotfix

# 实验/POC
experiment/new-caching-strategy
poc/graphql-migration

分支清理

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

# 删除已删除远程分支的远程跟踪引用
git fetch -p

# 删除本地分支
git branch -d feature/user-auth  # 安全删除(仅当已合并)
git branch -D feature/user-auth  # 强制删除

# 删除远程分支
git push origin --delete feature/user-auth

Stash 工作流

# 保存工作进度
git stash push -m "WIP: user authentication"

# 列出 stash
git stash list

# 应用最近的 stash
git stash pop

# 应用特定 stash
git stash apply stash@{2}

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

发布管理

语义化版本

MAJOR.MINOR.PATCH

MAJOR:破坏性变更
MINOR:新功能,向后兼容
PATCH:错误修复,向后兼容

示例:
1.0.0 → 1.0.1(补丁:错误修复)
1.0.1 → 1.1.0(次要:新功能)
1.1.0 → 2.0.0(主要:破坏性变更)

创建发布

# 创建附注标签
git tag -a v1.2.0 -m "Release v1.2.0

功能:
- 添加用户认证
- 实现密码重置

修复:
- 解决登录重定向问题

破坏性变更:
- 无"

# 推送标签到远程
git push origin v1.2.0

# 列出标签
git tag -l

# 删除标签
git tag -d v1.2.0
git push origin --delete v1.2.0

生成变更日志

# 从提交生成变更日志
git log v1.1.0..v1.2.0 --oneline --no-merges

# 或使用 conventional-changelog
npx conventional-changelog -i CHANGELOG.md -s

Git 配置

基本配置

# 用户身份
git config --global user.name "Your Name"
git config --global user.email "your@email.com"

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

# 拉取行为(使用变基而非合并)
git config --global pull.rebase true

# 推送行为(仅推送当前分支)
git config --global push.default current

# 自动纠正拼写错误
git config --global help.autocorrect 1

# 更好的差异算法
git config --global diff.algorithm histogram

# 彩色输出
git config --global color.ui auto

有用的别名

# 添加到 ~/.gitconfig
[alias]
    co = checkout
    br = branch
    ci = commit
    st = status
    unstage = reset HEAD --
    last = log -1 HEAD
    visual = log --oneline --graph --all
    amend = commit --amend --no-edit
    wip = commit -m "WIP"
    undo = reset --soft HEAD~1
    contributors = shortlog -sn

Gitignore 模式

# 依赖
node_modules/
vendor/

# 构建输出
dist/
build/
*.o
*.exe

# 环境文件
.env
.env.local
.env.*.local

# IDE
.idea/
.vscode/
*.swp
*.swo

# 操作系统文件
.DS_Store
Thumbs.db

# 日志
*.log
logs/

# 测试覆盖率
coverage/

# 缓存
.cache/
*.tsbuildinfo

常见工作流

开始一个新功能

# 1. 更新 main 分支
git checkout main
git pull origin main

# 2. 创建功能分支
git checkout -b feature/user-auth

# 3. 进行更改并提交
git add .
git commit -m "feat(auth): implement OAuth2 login"

# 4. 推送到远程
git push -u origin feature/user-auth

# 5. 在 GitHub/GitLab 上创建 Pull Request

用新更改更新 PR

# 1. 进行额外更改
git add .
git commit -m "feat(auth): add error handling"

# 2. 推送更新
git push origin feature/user-auth

同步 Fork 与上游

# 1. 添加上游远程(一次)
git remote add upstream https://github.com/original/repo.git

# 2. 获取上游
git fetch upstream

# 3. 将 upstream/main 合并到你的 main
git checkout main
git merge upstream/main

# 4. 推送到你的 fork
git push origin main

撤销错误

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

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

# 撤销已推送到远程的上次提交
git revert HEAD
git push origin main

# 撤销特定文件的更改
git checkout HEAD -- path/to/file

# 修复上次提交信息
git commit --amend -m "New message"

# 将忘记的文件添加到上次提交
git add forgotten-file
git commit --amend --no-edit

Git 钩子

Pre-Commit 钩子

#!/bin/bash
# .git/hooks/pre-commit

# 运行 lint
npm run lint || exit 1

# 运行测试
npm test || exit 1

# 检查密钥
if git diff --cached | grep -E '(password|api_key|secret)'; then
    echo "检测到可能的密钥。提交已中止。"
    exit 1
fi

Pre-Push 钩子

#!/bin/bash
# .git/hooks/pre-push

# 运行完整测试套件
npm run test:all || exit 1

# 检查 console.log 语句
if git diff origin/main | grep -E 'console\.log'; then
    echo "推送前请移除 console.log 语句。"
    exit 1
fi

反模式

# 差:直接提交到 main
git checkout main
git commit -m "fix bug"

# 好:使用功能分支和 PR

# 差:提交密钥
git add .env  # 包含 API 密钥

# 好:添加到 .gitignore,使用环境变量

# 差:巨大的 PR(1000+ 行)
# 好:拆分成更小、更专注的 PR

# 差:"Update" 提交信息
git commit -m "update"
git commit -m "fix"

# 好:描述性信息
git commit -m "fix(auth): resolve redirect loop after login"

# 差:重写公共历史
git push --force origin main

# 好:对公共分支使用 revert
git revert HEAD

# 差:长期存在的功能分支(数周/数月)
# 好:保持分支短期(数天),频繁变基

# 差:提交生成的文件
git add dist/
git add node_modules/

# 好:添加到 .gitignore

快速参考

任务 命令
创建分支 git checkout -b feature/name
切换分支 git checkout branch-name
删除分支 git branch -d branch-name
合并分支 git merge branch-name
变基分支 git rebase main
查看历史 git log --oneline --graph
查看更改 git diff
暂存更改 git add .git add -p
提交 git commit -m "message"
推送 git push origin branch-name
拉取 git pull origin branch-name
暂存 git stash push -m "message"
撤销上次提交 git reset --soft HEAD~1
回滚提交 git revert HEAD