GitHub 团队协作完整教程
前置要求:已掌握 Git 基础命令(add/commit/branch/push/pull 等);拥有 GitHub 账号。 本教程聚焦团队协作场景下的 GitHub 平台实操,是 Git 基础命令的延伸,覆盖互联网企业 99% 的日常协作场景。
一、协作核心认知
1. 本地 Git 与 GitHub 的关系
- 本地 Git:管理代码版本,是单机工具
- GitHub:远程代码托管平台,是团队协作的枢纽
- 核心区别:单人开发可以直接
push到主分支;团队协作必须通过 Pull Request(PR) 进行评审后合并,禁止直接向主分支提交代码。
2. 协作的本质
团队协作不是“各自写代码往上推”,而是:
基于分支开发 → 提交 PR → 代码评审 → 自动化检查 → 合并入主分支 → 发布上线
二、主流团队工作流
团队会统一遵循一套分支管理规则,避免分支混乱,最常用的是以下两种。
1. GitHub Flow(互联网团队首选,轻量敏捷)
绝大多数业务团队、敏捷开发都采用这套流程,简单高效。
核心规则
main/master分支永远是稳定、可发布的状态- 开发任何需求,都从
main拉出一条新的功能分支 - 功能开发完成后,提交 Pull Request
- 代码评审通过、自动化检查通过后,合并回
main - 合并完成后,删除功能分支
适用场景
业务迭代快、持续发布的项目,如 Web 后端、前端应用。
2. Git Flow(中重型,严格版本管理)
适合有明确版本发布周期的项目,如桌面软件、客户端应用。
核心分支
- 长期分支:
main(生产环境)、develop(开发环境) - 临时分支:
feature/(功能)、release/(版本发布)、hotfix/(线上紧急修复)
适用场景
版本号清晰、发布周期固定的传统软件项目。
工作提示:入职先问团队「用的什么工作流、主分支叫什么」,90% 以上的互联网团队用的是简化版 GitHub Flow。
三、Pull Request (PR) 全流程实战
PR 是 GitHub 协作的核心,全称 Pull Request(拉取请求),本质是「我开发完了,请求把我的分支合并进主分支,请先帮我评审」。
1. 完整操作步骤
步骤1:本地创建分支开发
# 切到主分支,拉取最新代码
git switch main
git pull origin main
# 创建功能分支
git switch -c feature/user-login
# 开发代码,提交
git add .
git commit -m "feat: 新增用户登录功能"步骤2:推送到远程仓库
git push -u origin feature/user-login步骤3:在 GitHub 创建 PR
- 打开仓库页面,会自动出现
Compare & pull request按钮,点击 - 选择合并方向:
base: main←compare: feature/user-login - 填写 PR 信息:
- 标题:清晰说明做了什么,如
feat: 新增用户登录模块 - 描述:改动背景、实现逻辑、测试情况,关联 Issue(如
closes #123)
- 标题:清晰说明做了什么,如
- 点击
Create pull request
步骤4:代码评审与修改
- 邀请团队成员作为评审人(Reviewer)
- 评审人提出意见,开发者根据意见修改代码
- 本地修改后直接
commit + push,提交会自动同步到 PR
步骤5:合并 PR
评审通过、自动化检查(CI)全部通过后,点击合并按钮。
步骤6:清理分支
合并完成后,点击 Delete branch 删除远程功能分支;本地也可以删除:
git switch main
git pull origin main
git branch -d feature/user-login2. 三种合并方式对比
PR 右下角有三种合并选项,团队必须统一选型:
| 合并方式 | 效果 | 适用场景 |
|---|---|---|
| Create a merge commit | 保留所有提交记录,生成一个合并节点 | 需要完整保留开发历史 |
| Squash and merge | 将 PR 内所有提交压缩成 1 个提交合入主分支 | ✅ 最常用,主分支历史干净整洁 |
| Rebase and merge | 变基合入,主分支呈完美线性,无合并节点 | 追求极致线性历史,仅私有分支使用 |
最佳实践:绝大多数团队统一使用 Squash and merge,功能分支的细碎提交不会污染主分支历史。
3. 实用 PR 技巧
- Draft PR:草稿模式,开发中先提交占位,标记为
Ready for review后才可以合并 - Reviewer 自动分配:通过
CODEOWNERS文件配置指定目录的默认评审人 - PR 模板:仓库配置 PR 模板,统一大家的描述格式
四、团队统一规范
没有规范的团队协作一定会混乱,以下是业界通用标准。
1. 分支命名规范
统一前缀命名,一眼识别分支用途:
feature/xxx # 新功能开发
fix/xxx # 修复 bug
hotfix/xxx # 线上紧急修复
docs/xxx # 文档更新
refactor/xxx # 代码重构
test/xxx # 测试相关
chore/xxx # 构建/工具/依赖变动示例:
feature/user-loginfix/payment-timeouthotfix/login-bypass
2. 提交信息规范(Conventional Commits)
业界最通用的提交信息规范,格式统一,可自动生成版本日志。
格式
<类型>: <描述>
# 可选:加作用域和正文
<类型>(<作用域>): <描述>
<空行>
<正文:动机与实现对比>
<空行>
<页脚:关联 Issue / BREAKING CHANGE>示例:
feat(auth): 增加手机号登录接口
fix(payment): 修复支付超时未回调问题 closes #123
docs(deploy): 更新部署与联调文档
refactor(user): 抽离用户信息公共方法常用类型详解(附划分指引与边界示例)
选型口诀:先问「这次改动有没有改变对外行为?」
- 变了(新增/修复/删除可见功能)→
feat/fix- 没变(内部调整、纯格式、文档、构建)→ 从下面
refactor/style/docs/chore/test/perf/ci/build里挑
| 类型 | 含义 | 典型场景 | 容易混淆的边界 |
|---|---|---|---|
feat | 新增用户可见的功能或模块 | 新增接口、新增页面、新增配置项、新增命令行参数 | 把私有工具函数当成 feat → 对外不可见应归 refactor;破坏性变更需在正文写 BREAKING CHANGE: |
fix | 修复 bug,修正不符合预期的行为 | 空指针、越界、支付回调丢失、文案错误 | 调整逻辑让它「更好」而非「修对」→ 用 refactor;修复构建/CI 脚本本身 → 用 ci 或 build |
docs | 仅改动文档 | README、注释、API 文档、CHANGELOG | 改了代码又顺手改注释 → 按主要改动定类型,别硬拆;注释算 docs |
style | 代码格式变动,不影响代码逻辑(无运行时影响) | 空格、缩进、分号、Prettier/ESLint 自动格式化、重命名不改变行为 | 改了逻辑后顺手格式化 → 拆成 fix/feat + style;加了类型注解影响编译 → 倾向 refactor |
refactor | 重构:不改变对外行为的代码结构调整 | 抽离公共方法、重命名变量/函数、拆分大类、替换内部算法、移除死代码 | 既重构又顺带修 bug → 拆两个 commit,或按主要意图选 fix 并在正文说明 |
perf | 改善性能,行为不变 | 优化查询、减少重渲染、加缓存、懒加载 | 性能改动同时改了 API → 归 feat;重构恰好变快 → 仍算 refactor |
test | 仅改动测试代码 | 新增单测/集成测试、补全用例、修复测试本身 | 测试文件和生产代码一起改 → 拆两个 commit 更准确 |
build | 构建系统、依赖、打包相关 | 改 package.json、pom.xml、Cargo.toml、webpack/vite 配置、锁文件 | 改 CI 配置 → 用 ci;改 Dockerfile → build |
ci | 持续集成 / 持续部署配置 | GitHub Actions、Jenkinsfile、.gitlab-ci.yml、流水线脚本 | 改部署相关的 Dockerfile → build;改流水线 → ci |
chore | 杂项:不属于以上类型的其他改动 | 改 .gitignore、更新许可证、调整目录、维护脚本 | 不确定归哪类时才用 chore,不要滥用当垃圾桶 |
revert | 回滚之前的某次提交 | 明确撤销某次改动 | 直接用 revert: <原 commit 标题> |
特殊标记(页脚 / 正文)
- BREAKING CHANGE:破坏性变更,必须升级且可能不兼容
feat(api): 重构用户接口 BREAKING CHANGE: /api/v1/users 改为 /api/v2/users,调用方需同步升级 - 关联 Issue:
closes #123、fixes #456、refs #789(不自动关闭,仅引用)
快速决策树(实操不知道选哪个时)
这次提交的主要意图是什么?
├─ 新增/扩展了用户可见功能? → feat
├─ 修正了错误/异常行为? → fix
├─ 只改了文档/注释? → docs
├─ 只改了格式/空格/命名(无逻辑)? → style
├─ 重构/重命名/抽离(行为不变)? → refactor
├─ 优化了性能(行为不变)? → perf
├─ 只改了测试代码? → test
├─ 改了依赖/打包/构建配置? → build
├─ 改了 CI/CD 流水线? → ci
├─ 实在都不像(杂项维护)? → chore
└─ 撤销之前某次提交? → revert一个提交只做一件事:如果一次提交同时「修 bug + 重构 + 改文档」,请拆成多个 commit,每个对应一个类型。拆不开时,按主要意图选一个类型,并在正文说明其他附带改动。
五、Issue 与任务管理
GitHub Issue 是团队的需求/缺陷/任务跟踪工具,所有工作都应该对应一条 Issue。
1. Issue 核心作用
- 记录需求、bug、优化建议、技术讨论
- 每条 Issue 有唯一编号、状态、标签、负责人
- 可以和 PR 关联,实现「需求 → 代码 → 合并」全链路追踪
2. 关联 PR 的技巧
在 PR 描述中写入以下关键字,合并 PR 后会自动关闭对应 Issue:
closes #123
fixes #456
resolves #7893. 辅助管理功能
- Labels(标签):给 Issue/PR 分类,如
bug、feature、priority: high、good first issue - Milestones(里程碑):将一组 Issue 归到一个版本/周期,如
v1.2.0,跟踪整体进度 - Projects(项目看板):看板式任务管理,状态流转:
待办 → 进行中 → 评审中 → 已完成 - Issue 模板:与 PR 模板类似,可配置
Bug report/Feature request等模板,规范需求提报格式(建议在仓库.github/ISSUE_TEMPLATE/下配置)
六、代码评审(Code Review)实操
代码评审是团队代码质量的保障,基于 PR 进行。
1. 评审流程
- 评审人查看 PR 改动,针对代码行评论
- 可以直接给出修改建议(Suggestion),开发者可一键应用
- 评审完成后选择评审结果:
- Approve:审批通过,可以合并
- Comment:普通意见,不强制修改
- Request changes:必须修改,修改后重新评审
2. 评审最佳实践
- 对事不对人,针对代码逻辑,不针对个人
- 尽量给出具体建议,而不是只说「这里写得不好」
- 大改动提前沟通,不要等到 PR 才全盘否定
- 评审意见分优先级:阻塞问题必须改,优化建议可讨论
七、GitHub Actions CI/CD 入门
现在的团队基本都会配置自动化检查,PR 提交后自动运行,是合并的门禁。
1. 核心作用
- 自动运行单元测试、代码风格检查、安全扫描
- 自动构建项目、打包镜像
- 自动部署到测试/生产环境
2. 基本概念
- 配置文件位置:仓库
.github/workflows/目录下,yml格式 - 触发时机:push、PR 创建、定时、手动触发
- 任务(Job):在虚拟机中执行的一系列步骤
3. 最简单示例:PR 自动运行测试
在 .github/workflows/ci.yml 写入以下内容:
name: CI
on:
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 运行测试
run: |
echo "安装依赖"
echo "运行单元测试"提交后,每个 PR 都会自动运行这个工作流,通过显示绿勾,不通过显示红叉。
新手只需看懂:红叉 = 检查没通过,不能合并;绿勾 = 检查通过。
八、协作安全与避坑指南
1. 分支保护规则(Branch Protection)
口头约定「不要直接 push 到 main」是不可靠的,企业级项目会用分支保护把它变成硬门禁。
建议配置(仓库 Settings → Branches → Branch protection rules)
- Require a pull request before merging:禁止直接 push,必须通过 PR
- Required number of approvals:至少 N 人审批(常见 1~2 人)
- Dismiss stale approvals when new commits are pushed:推送新提交后取消旧审批,需重新评审
- Require status checks to pass(Require CI):CI 必须通过才能合并
- Require branches to be up to date:合并前必须包含 main 最新提交,避免落后于主干
- Require linear history:禁止 merge commit,仅允许 squash/rebase,保持历史线性
- Include administrators:保护规则对管理员也生效(强烈推荐)
- Allow force pushes:默认关闭,禁止对主分支强推
- Restrict deletions:禁止删除主分支
最佳实践:
main分支应最小化可写权限 + 全量保护规则,合并仅靠 PR + 审批 + CI 绿勾三重保障。
2. .gitignore 最佳实践
- 不要提交依赖包、IDE 配置、本地环境文件、日志
- 直接使用官方标准模板:github/gitignore
- 已经提交的文件想忽略:bash
git rm --cached 文件名 # 再加入 .gitignore 并提交
3. 敏感信息绝对不能提交
- 密码、密钥、Token、私钥禁止写进代码
- 一旦提交,即使删除也会永久留在历史记录中
- 补救方法:
- 立即轮换泄露的密钥
- 使用
git filter-repo等工具改写提交历史
- 敏感配置使用环境变量或 GitHub Secrets 管理
4. 权限与账号安全
- 推荐使用 SSH 密钥连接仓库,无需每次输入密码
- 开启账号双因素认证(2FA)
- 个人访问令牌(PAT)只授予最小权限,定期轮换
5. 依赖安全
- 开启 GitHub Dependabot,自动检测依赖漏洞并提交升级 PR
- 定期更新项目依赖,避免安全隐患
九、进阶协作技巧
1. Fork 与上游同步(开源贡献常用)
外部开发者先 Fork 仓库到自己账号,修改后从 Fork 仓库提 PR 到上游仓库。 同步上游更新:
git remote add upstream 上游仓库地址
git fetch upstream
git switch main
git merge upstream/main适用场景说明:
- Fork 模式:主要用于开源社区,或跨团队、无上游仓库写权限的协作。
- 公司内部:通常直接被添加为仓库
Collaborator或加入团队,获得推送分支权限后直接建分支推送到同一仓库,无需 Fork。一句话:有写权限 → 直接分支;没写权限 → Fork。不要在公司内部项目也习惯性 Fork,反而增加同步成本。
2. 功能分支开发中途同步 main 分支(Rebase 实践)
功能分支开发周期较长时,main 已经往前走了很多提交,最终合并容易产生大量冲突。建议定期把 main 的最新代码同步到自己的功能分支:
# 方式一:rebase(推荐,保持历史线性)
git fetch origin
git rebase origin/main
# 解决冲突后:git rebase --continue
# 方式二:merge(保留合并节点,适合不熟悉 rebase 的团队)
git fetch origin
git merge origin/main注意事项
- 本地尚未推送的提交:可以放心 rebase
- 已经推送到远程的提交:rebase 会改变 commit hash,需要
git push --force-with-lease(比--force更安全,会检查远端是否被别人更新过) - 永远不要对已合并的提交或公共分支(main/develop)做 rebase
- 团队若无特殊约定,
Squash and merge后主分支天然线性,个人分支 rebase 频率不必过高,遇到冲突再同步即可
3. 整理提交历史(amend / rebase -i)
既然团队用 Squash and merge,PR 内的细碎提交其实会被压成一个,影响有限。但如果想让 Reviewer 看得更舒服,可以在本地整理:
# 修改最近一次提交(补充改动 / 修改 commit message)
git commit --amend
# 交互式整理最近 N 次提交(合并、重排、修改 message)
git rebase -i HEAD~N黄金法则:
amend和rebase -i只用于未推送的本地提交;一旦 push 到远程(尤其是 PR 已开启),重写历史会让协作者混乱。若必须重写已推送历史,务必先和团队沟通,并用--force-with-lease。
4. Git Submodule(子模块)
项目依赖其他仓库代码时使用,比如公共组件库,一个仓库嵌套另一个仓库。
5. Release 版本发布
基于 Git Tag 发布正式版本,可上传安装包、编写更新日志,用户可下载历史版本。
6. Gist
用来存放零散代码片段、配置文件、笔记,支持公开/私密,分享方便。
十、完整实战演练:从需求到上线
模拟真实工作流,走完全流程:
- 创建 Issue:在 GitHub 新建 Issue「新增用户登录功能」,编号 #1
- 拉取主分支:本地
git switch main && git pull - 创建功能分支:
git switch -c feature/user-login - 开发提交:编码完成,
git commit -m "feat: 新增用户登录功能"- (可选)开发中定期同步主干:
git fetch origin && git rebase origin/main
- (可选)开发中定期同步主干:
- 推送远程:
git push -u origin feature/user-login - 创建 PR:关联 Issue #1,描述写
closes #1 - 代码评审:邀请同事评审,根据意见修改提交
- (可选)评审意见较多时本地整理历史:
git rebase -i/git commit --amend
- (可选)评审意见较多时本地整理历史:
- CI 检查通过:自动化测试显示绿勾
- 合并 PR:选择 Squash and merge(满足分支保护的审批 + CI 要求)
- 清理分支:删除远程分支,本地拉取最新主分支代码
常见问题 FAQ
- PR 合并冲突了怎么办? 页面会提示冲突,有两种方式:
- 页面上点击
Resolve conflicts在线解决 - 本地拉取主分支最新代码,合并到自己的分支,解决冲突后推送
推荐本地解决:用
git fetch origin && git rebase origin/main(或git merge origin/main),解决完 push 即可。 - 页面上点击
- 提交错了分支怎么办? 用
git cherry-pick把提交移到正确的分支,再重置错误分支。 - 可以直接 push 到 main 吗? 团队项目一般会给主分支加保护规则(见第八章),禁止直接 push,必须走 PR。
- rebase 和 merge 到底选哪个同步主干?
- 追求干净线性历史、且是个人私有分支 →
rebase - 团队约定保留合并节点、或不想改写历史 →
merge - 不确定时:跟着团队默认规范走,一致性 > 个人偏好。
- 追求干净线性历史、且是个人私有分支 →
- 一个提交同时包含多种改动类型怎么办? 优先拆成多个 commit,每个对应一个类型;实在拆不开,按主要意图选一个类型,并在正文说明附带改动。
附录:快速命令速查表
# 日常开发
git switch main && git pull # 拉取最新主干
git switch -c feature/xxx # 新建功能分支
git add . && git commit -m "feat: ..." # 提交(遵循规范)
git push -u origin feature/xxx # 推送到远程
# 同步主干(开发中途)
git fetch origin
git rebase origin/main # 线性方式(推荐)
# git merge origin/main # 合并方式
# 整理历史(仅本地未推送时)
git commit --amend # 修改最近一次提交
git rebase -i HEAD~N # 交互式整理
# 清理
git switch main && git pull
git branch -d feature/xxx # 删除已合并的本地分支一句话总结:协作的本质是「规范先行、PR 为中枢、CI 为门禁、保护规则兜底」。掌握这套组合,就能无缝融入任何互联网团队的工程节奏。

