跳转至

远程协作

🎯 学习目标

  • 理解远程仓库的概念与工作原理
  • 熟练使用 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 之后需要手动合并:

Bash
git fetch origin
git log origin/main --oneline     # 查看远程更新
git merge origin/main             # 合并到当前分支

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

⚠️ --force vs --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 预防冲突的团队策略

  1. CODEOWNERS 文件:定义代码的负责人
Text Only
# .github/CODEOWNERS
*.js        @frontend-team
*.py        @backend-team
/docs/      @tech-writer
/infra/     @devops-team
  1. Branch Protection Rules
  2. 要求 PR 审核通过才能合并
  3. 要求 CI 通过
  4. 要求分支是最新的(up-to-date with base branch)
  5. 禁止强制推送

  6. 沟通机制

  7. 每日站会同步进展
  8. 修改公共模块前在群里通知
  9. 使用 GitHub Projects 跟踪任务分配

✏️ 练习题

基础练习

  1. 在 GitHub 上创建一个仓库,完成以下操作:
  2. 本地克隆仓库
  3. 创建 Feature 分支并推送
  4. 在 GitHub 上创建 Pull Request
  5. 合并 PR 后删除远程分支

  6. 练习 git fetchgit pull 的区别:

  7. 在 GitHub 上直接编辑一个文件
  8. 本地执行 git fetch,查看 origin/main 的变化
  9. 执行 git merge origin/main 完成合并

  10. 练习标签操作:

  11. 创建附注标签 v1.0.0
  12. 推送标签到 GitHub
  13. 在 GitHub Releases 中创建发布说明

进阶练习

  1. 完整体验 Fork + PR 开源贡献流程:
  2. Fork 一个朋友的仓库
  3. 克隆、修改、提交、推送
  4. 创建 PR

  5. 配置 GitHub Actions:

  6. 创建一个简单的 CI 流水线
  7. 验证每次 push 自动运行测试

  8. 模拟多人协作冲突:

  9. 克隆仓库到两个不同目录(模拟两个开发者)
  10. 修改同一文件的同一行
  11. 练习解决冲突

📋 面试要点

  • git fetch vs git pull:fetch 只下载不合并,pull = fetch + merge
  • --force vs --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

← 上一章:分支管理 | 下一章:高级技巧 →