远程协作¶
🎯 学习目标¶
- 理解远程仓库的概念与工作原理
- 熟练使用 git remote、fetch、pull、push 命令
- 掌握 Pull Request / Merge Request 工作流
- 了解 Fork 模式与开源贡献流程
- 掌握 Code Review 最佳实践
- 熟悉 GitHub / GitLab 的协作功能
- 能够处理多人协作中的冲突
1. 远程仓库概念¶
远程仓库是托管在网络上的 Git 仓库副本,用于团队协作和代码备份。
Text Only
本地仓库 远程仓库
┌─────────────┐ ┌─────────────┐
│ Working Dir │ │ │
│ Staging Area │ ◄── git fetch ── │ origin │
│ Local Repo │ ── git push ──► │ (GitHub等) │
│ │ │ │
│ origin/main │ (远程跟踪分支) │ main │
└─────────────┘ └─────────────┘
关键概念:
- 远程跟踪分支(如
origin/main):本地保存的远程分支快照,只通过fetch/pull更新 - origin:默认的远程仓库别名(可以有多个远程仓库)
- upstream:通常指向原始仓库(Fork 场景)
2. git remote 管理¶
Bash
# 查看远程仓库
git remote # 显示远程仓库名称
git remote -v # 显示详细的 URL 信息
# 添加远程仓库
git remote add origin git@github.com:user/repo.git
git remote add upstream git@github.com:original/repo.git
# 修改远程仓库 URL
git remote set-url origin git@github.com:user/new-repo.git
# 重命名远程仓库
git remote rename origin github
# 删除远程仓库关联
git remote remove upstream
# 查看远程仓库详情
git remote show origin
3. git fetch / git pull / git push¶
3.1 git fetch(获取远程更新)¶
fetch 只下载远程仓库的数据,不会自动合并到当前分支。
Bash
# 获取默认远程仓库的所有更新
git fetch
# 获取指定远程仓库
git fetch origin
# 获取指定分支
git fetch origin main
# 获取所有远程仓库
git fetch --all
# 清理已删除的远程分支的本地跟踪
git fetch --prune
fetch 之后需要手动合并:
3.2 git pull(获取并合并)¶
pull = fetch + merge(或 fetch + rebase)。
Bash
# 基本拉取(fetch + merge)
git pull
# 指定远程和分支
git pull origin main
# 使用 rebase 模式(推荐,避免生成额外 merge commit)
git pull --rebase
git pull --rebase origin main
# 设置默认 pull 策略为 rebase
git config --global pull.rebase true
# 只允许 Fast-forward 模式的 pull
git config --global pull.ff only
💡 推荐:设置
pull.rebase true,保持提交历史线性清洁。
3.3 git push(推送到远程)¶
Bash
# 基本推送
git push origin main
# 推送当前分支(设置后可省略分支名)
git push -u origin feature/login # -u 设置上游分支
git push # 之后直接 push 即可
# 推送所有分支
git push --all origin
# 推送标签
git push origin v1.0.0 # 推送指定标签
git push origin --tags # 推送所有标签
# 强制推送(⚠️ 危险!)
git push --force # 强制覆盖远程
git push --force-with-lease # 更安全的强制推送(检查远程是否有新提交)
# 删除远程分支
git push origin --delete feature/login
⚠️
--forcevs--force-with-lease: ---force无条件覆盖远程,可能丢失别人的提交 ---force-with-lease会检查远程分支是否有你没见过的提交,更安全
4. Pull Request / Merge Request 工作流¶
Pull Request(GitHub 叫法)和 Merge Request(GitLab 叫法)是同一概念:请求将你的分支合并到目标分支。
4.1 标准 PR 流程¶
Text Only
1. 从 main 创建 Feature 分支
git switch -c feature/user-profile
2. 开发、提交
git add .
git commit -m "feat(user): 添加用户资料页面"
3. 推送到远程
git push -u origin feature/user-profile
4. 在 GitHub/GitLab 上创建 Pull Request
- 填写标题和描述
- 指定 Reviewer
- 关联 Issue(如 Closes #123)
5. Code Review
- Reviewer 审查代码、提出意见
- 开发者根据反馈修改并推送新提交
6. CI 检查通过
7. 合并 PR
- Merge commit(保留分支历史)
- Squash and merge(压缩为一个提交)✨ 推荐
- Rebase and merge(变基后合并)
8. 删除 Feature 分支
4.2 PR 描述模板¶
Markdown
## 描述
简述本次改动的目的和内容。
## 改动类型
- [ ] 新功能 (feat)
- [ ] Bug修复 (fix)
- [ ] 文档更新 (docs)
- [ ] 代码重构 (refactor)
- [ ] 性能优化 (perf)
- [ ] 测试 (test)
## 关联 Issue
Closes #123
## 测试说明
描述如何测试本次改动。
## 截图(如有UI变更)
## Checklist
- [ ] 代码符合项目规范
- [ ] 已添加/更新测试
- [ ] 已更新文档
- [ ] CI 检查通过
4.3 三种合并方式对比¶
| 方式 | 历史 | 适用场景 |
|---|---|---|
| Merge commit | 保留所有提交+合并节点 | 需要完整历史的场景 |
| Squash and merge | 多个提交压缩为一个 | Feature分支提交较杂乱 |
| Rebase and merge | 线性追加提交 | 提交已经很整洁 |
💡 推荐:大多数团队使用 Squash and merge,保持主分支历史干净。
5. Fork 模式(开源贡献流程)¶
Fork 是 GitHub/GitLab 的功能,可以将别人的仓库复制一份到你的账号下。
5.1 完整的开源贡献流程¶
Bash
# 1. Fork 仓库(在 GitHub 页面操作)
# 2. 克隆你 Fork 的仓库
git clone git@github.com:YOUR_USER/project.git
cd project
# 3. 添加上游仓库
git remote add upstream git@github.com:ORIGINAL_OWNER/project.git
git remote -v
# origin git@github.com:YOUR_USER/project.git (fetch)
# origin git@github.com:YOUR_USER/project.git (push)
# upstream git@github.com:ORIGINAL_OWNER/project.git (fetch)
# upstream git@github.com:ORIGINAL_OWNER/project.git (push)
# 4. 同步上游最新代码
git fetch upstream
git switch main
git merge upstream/main
git push origin main # 更新你的 Fork
# 5. 创建功能分支
git switch -c fix/typo-in-readme
# 6. 开发并提交
git add .
git commit -m "docs: 修复 README 中的拼写错误"
# 7. 推送到你的 Fork
git push origin fix/typo-in-readme
# 8. 在 GitHub 上创建 Pull Request
# 从 YOUR_USER/project:fix/typo-in-readme → ORIGINAL_OWNER/project:main
# 9. 等待 Review,根据反馈修改
# 10. PR 被合并后清理
git switch main
git branch -d fix/typo-in-readme
git push origin --delete fix/typo-in-readme
5.2 保持 Fork 同步¶
Bash
# 定期执行(每次开始新工作前)
git fetch upstream
git switch main
git rebase upstream/main
git push origin main
6. Code Review 最佳实践¶
6.1 作为 Reviewer¶
- 及时 Review:不要让 PR 在那里等太久(理想 < 24小时)
- 理解上下文:先看 PR 描述和关联 Issue
- 分层审查:
- 第一遍:整体架构和设计
- 第二遍:具体实现细节
- 第三遍:边界情况和错误处理
- 建设性反馈:解释"为什么不好",而不只是"这不行"
- 区分严重程度:
- 🔴 Must fix:bug、安全问题
- 🟡 Should fix:代码质量问题
- 🟢 Nit/建议:风格偏好,非阻塞
- 赞美好的代码:看到优雅的实现,别吝啬夸奖
6.2 作为 Author¶
- 小 PR:每个 PR 控制在 200-400 行变更以内
- 自审一遍:提交前自己先 Review 一遍
- 写好描述:清楚说明改了什么、为什么改、怎么测的
- 及时响应:对 Review 意见积极回应
- 不要人身攻击:Code Review 是对代码,不是对人
7. GitHub 协作功能¶
7.1 Issues & Projects¶
Issues 是项目管理的核心:
Markdown
## Issue 模板
### Bug Report
**描述**:简述bug
**复现步骤**:
1. 打开xx页面
2. 点击xx按钮
3. 观察到xx错误
**期望行为**:应该显示xx
**实际行为**:显示了xx
**环境**:OS/Browser/Version
### Feature Request
**需求描述**:
**使用场景**:
**实现建议**:
GitHub Projects(看板管理):
Text Only
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Backlog │ │ Todo │ │ In │ │ Done │
│ │ │ │ │ Progress │ │ │
│ #15 │ │ #12 │ │ #8 │ │ #3 │
│ #16 │ │ #13 │ │ #10 │ │ #5 │
│ #17 │ │ │ │ │ │ #7 │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
7.2 GitHub Actions(CI/CD)¶
GitHub Actions 是 GitHub 内置的持续集成/持续交付平台。
YAML
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Run lint
run: npm run lint
常见 CI/CD 场景:
| 触发事件 | 执行任务 |
|---|---|
| Push to main | 运行测试 → 构建 → 部署到生产 |
| Pull Request | 运行测试 → Lint 检查 → 构建验证 |
| 定时触发 | 依赖安全扫描、性能测试 |
| 发布 Release | 构建产物 → 发布到包管理器 |
7.3 GitHub Pages¶
免费的静态网站托管服务。
Bash
# 方式一:使用 gh-pages 分支
git switch --orphan gh-pages
# 添加静态文件
git push origin gh-pages
# 方式二:在 Settings → Pages 中配置
# 选择分支和目录(如 main 分支的 /docs 目录)
7.4 Releases & Tags¶
标签(Tags)用于标记重要的版本节点:
Bash
# 创建轻量标签
git tag v1.0.0
# 创建附注标签(推荐)
git tag -a v1.0.0 -m "Release version 1.0.0"
# 查看标签
git tag
git tag -l "v1.*"
# 推送标签到远程
git push origin v1.0.0
git push origin --tags
# 基于标签创建分支
git switch -c hotfix/v1.0.1 v1.0.0
# 删除标签
git tag -d v1.0.0 # 本地删除
git push origin --delete v1.0.0 # 远程删除
语义化版本号(Semantic Versioning):
Text Only
v MAJOR.MINOR.PATCH
│ │ │
│ │ └── 补丁版本:bug修复,向后兼容
│ └──────── 次版本号:新功能,向后兼容
└─────────────── 主版本号:不兼容的API变更
示例:
v1.0.0 → v1.0.1 (bugfix)
v1.0.1 → v1.1.0 (new feature)
v1.1.0 → v2.0.0 (breaking change)
8. GitLab 协作功能简介¶
GitLab 提供了类似 GitHub 的功能,但也有独特之处:
| 功能 | GitHub | GitLab |
|---|---|---|
| 代码审查 | Pull Request | Merge Request |
| CI/CD | GitHub Actions | GitLab CI/CD(.gitlab-ci.yml) |
| 项目管理 | Projects (Board) | Issue Boards + Milestones |
| 静态网站 | GitHub Pages | GitLab Pages |
| 容器注册 | GitHub Packages | GitLab Container Registry |
| 自托管 | GitHub Enterprise | GitLab CE(免费开源)✨ |
| Wiki | 内置 | 内置,功能更强 |
GitLab CI/CD 示例:
YAML
# .gitlab-ci.yml
stages:
- test
- build
- deploy
test:
stage: test
image: python:3.12
script:
- pip install -r requirements.txt
- pytest
build:
stage: build
script:
- docker build -t myapp .
only:
- main
deploy:
stage: deploy
script:
- ./deploy.sh
only:
- tags
9. 多人协作冲突处理实战¶
9.1 场景:同时修改同一文件¶
Bash
# 开发者A:
git switch -c feature-a
# 修改 app.py 的第10行
git commit -am "feat: 修改数据库连接"
git push origin feature-a
# 开发者B:
git switch -c feature-b
# 同样修改 app.py 的第10行
git commit -am "feat: 修改缓存配置"
git push origin feature-b
# 合并 feature-a 到 main(成功)
# 合并 feature-b 到 main(冲突!)
9.2 解决方案¶
Bash
# 开发者B 需要先更新自己的分支
git switch feature-b
git fetch origin
git rebase origin/main
# 冲突!手动解决后:
git add .
git rebase --continue
git push --force-with-lease origin feature-b
# 然后重新请求合并
9.3 预防冲突的团队策略¶
- CODEOWNERS 文件:定义代码的负责人
Text Only
# .github/CODEOWNERS
*.js @frontend-team
*.py @backend-team
/docs/ @tech-writer
/infra/ @devops-team
- Branch Protection Rules:
- 要求 PR 审核通过才能合并
- 要求 CI 通过
- 要求分支是最新的(up-to-date with base branch)
-
禁止强制推送
-
沟通机制:
- 每日站会同步进展
- 修改公共模块前在群里通知
- 使用 GitHub Projects 跟踪任务分配
✏️ 练习题¶
基础练习¶
- 在 GitHub 上创建一个仓库,完成以下操作:
- 本地克隆仓库
- 创建 Feature 分支并推送
- 在 GitHub 上创建 Pull Request
-
合并 PR 后删除远程分支
-
练习
git fetch和git pull的区别: - 在 GitHub 上直接编辑一个文件
- 本地执行
git fetch,查看origin/main的变化 -
执行
git merge origin/main完成合并 -
练习标签操作:
- 创建附注标签
v1.0.0 - 推送标签到 GitHub
- 在 GitHub Releases 中创建发布说明
进阶练习¶
- 完整体验 Fork + PR 开源贡献流程:
- Fork 一个朋友的仓库
- 克隆、修改、提交、推送
-
创建 PR
-
配置 GitHub Actions:
- 创建一个简单的 CI 流水线
-
验证每次 push 自动运行测试
-
模拟多人协作冲突:
- 克隆仓库到两个不同目录(模拟两个开发者)
- 修改同一文件的同一行
- 练习解决冲突
📋 面试要点¶
git fetchvsgit pull:fetch 只下载不合并,pull = fetch + merge--forcevs--force-with-lease:后者更安全,会检查远程状态- Pull Request 流程:创建分支 → 开发 → Push → 创建PR → Review → 合并
- Fork 模式:用于开源贡献,配合 upstream 远程仓库使用
- 三种 PR 合并方式:Merge commit、Squash and merge、Rebase and merge
- 语义化版本号:MAJOR.MINOR.PATCH
- Branch Protection:保护重要分支的安全机制
- CODEOWNERS:定义代码负责人,自动分配 Reviewer