与他人协作是 Git 的核心价值所在。远程仓库不是“云端备份”,而是团队共享历史、审查变更和发布版本的协调点。理解远程协作,重点不是背协议,而是知道什么身份能写、什么历史能改、什么变更需要审查。
1. Git 传输协议
Git 使用四种不同的协议来传输数据:本地协议、HTTP(S)、SSH 和 Git 协议。
| 协议 | 传输方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 本地协议 | 文件系统路径 | 简单、无需网络 | 无权限控制 | 本地备份 |
| HTTP(S) | HTTP/HTTPS | 穿透防火墙、广泛支持 | 效率略低 | 通用场景 |
| SSH | SSH 隧道 | 安全、高效 | 需配置密钥 | 开发者日常 |
| Git 协议 | git:// 端口 9418 | 速度最快 | 无认证 | 只读公共仓库 |
本地协议:最基本的协议,远程仓库是同一主机上的另一个目录。适合团队共享文件系统(如 NFS)的场景,但不适合多人共用一台电脑,因为存在单点故障风险。
HTTP(S):分为智能 HTTP 和哑 HTTP 两种模式。智能 HTTP 支持用户名/密码认证,无需配置 SSH 密钥,对企业防火墙友好,是通用场景的首选。
SSH:最常用的协议,所有传输数据经过授权和加密。大多数服务器已支持 SSH 访问,架设简单。缺点是不支持匿名只读访问。
Git 协议:Git 自带的特殊守护进程,监听 9418 端口,是最快的传输协议。但缺乏认证机制,通常只用于只读公共仓库,需配合 SSH 或 HTTPS 提供写权限。
2. 第三方托管
如果不想自己架设和维护 Git 服务器,可以使用第三方托管服务。GitHub、GitLab、Gitee 等平台的价值不只是托管仓库,还包括 Issue、PR/MR、CI、Release、权限和审查记录。现代工程协作通常围绕这些平台对象展开,而不仅是 git push。
3. 分布式工作流
与传统的集中式版本控制系统(CVCS)不同,Git 的分布式特性让每个开发者既是节点也是集线器——你既可以向其他仓库贡献代码,也可以维护自己的公开仓库供他人使用。
集中式工作流
集中式系统通常使用单点协作模型。一个中心仓库接受所有代码,所有开发者与之同步。每个开发者作为节点,从中心仓库拉取更新并推送自己的修改。这是从 SVN 等集中式系统迁移过来的团队最熟悉的工作模式。
集成管理者工作流
Git 允许多个远程仓库存在,每个开发者拥有自己仓库的写权限和其他人仓库的读权限。通常有一个代表”官方”项目的权威仓库,贡献流程如下:
- 项目维护者推送到主仓库。
- 贡献者克隆此仓库,做出修改。
- 贡献者将数据推送到自己的公开仓库。
- 贡献者给维护者发送邮件,请求拉取自己的更新。
- 维护者在本地仓库中将贡献者的仓库添加为远程仓库并合并修改。
- 维护者将合并后的修改推送到主仓库。
主管与副主管工作流
这是多仓库工作流的变种,适合拥有数百位协作开发者的超大型项目(如 Linux 内核)。副主管(lieutenant)负责集成项目的特定部分,主管(dictator)作为总集成者统筹全局:
- 普通开发者在自己的主题分支上工作,并根据主管的 master 分支进行变基。
- 副主管将普通开发者的主题分支合并到自己的 master 分支中。
- 主管将所有副主管的 master 分支并入自己的 master 分支中。
- 主管将集成后的 master 分支推送到参考仓库,供所有开发者拉取。
4. 向项目贡献
向项目贡献的方式因项目而异,主要取决于活跃贡献者数量、项目使用的工作流以及提交权限。
提交准则
良好的提交信息是协作的基础。遵循以下格式:
首字母大写的摘要(不多于 50 个字符)
如果必要的话,加入更详细的解释文字。在大概 72 个字符的时候换行。
在某些情形下,第一行被当作一封电子邮件的标题,剩下的文本作为正文。
分隔摘要与正文的空行是必须的(除非你完全省略正文),
如果你将两者混在一起,那么类似变基等工具无法正常工作。
使用指令式的语气来编写提交信息:使用"Fix bug"而非"Fixed bug"或"Fixes bug"。
此约定与 git merge 和 git revert 命令生成提交说明相同。
空行接着更进一步的段落。
- 标号也是可以的。
- 项目符号可以使用典型的连字符或星号,后跟一个空格,行之间用空行隔开,
但是可以依据不同的惯例有所不同。
- 使用悬挂式缩进通过 Fork 的公开项目
这是向开源项目贡献的常见方式。核心判断是:主仓库由维护者控制,贡献者在自己的 Fork 中工作,通过 PR 把变更提交给维护者审查。
# 克隆远程仓库
git clone <url>
# 切换至项目目录
cd project
# 创建并切换至特性分支
git checkout -b featureA
# ... 工作 ...
git commit
# ... 工作 ...
git commit当分支工作完成后,在原项目中点击 Fork 按钮创建一份自己的可写派生仓库。然后在本地添加该仓库为新的远程仓库:
# 添加 fork 仓库
git remote add myfork <url>
# 推送特性分支
git push -u myfork featureA推送完成后,通过托管平台生成**拉取请求(Pull Request)**通知原项目维护者。你也可以运行 git request-pull 命令,将输出手动发送给维护者。
建议始终保留一个跟踪 origin/master 的 master 分支,在独立的主题分支上工作。这样如果贡献被拒绝,你可以轻松丢弃;如果主仓库更新了,你也更容易进行变基。
通过邮件的公开项目
有些项目偏好通过邮件接受贡献补丁。邮件工作流看起来传统,但它强调的是补丁本身、提交历史和维护者审核链路,Linux 内核等大型项目仍然使用这种模式。
# 克隆远程仓库
git clone <url>
# 切换至项目目录
cd project
# 创建并切换至特性分支
git checkout -b topicA
# ... 工作 ...
git commit
# ... 工作 ...
git commit使用 git format-patch 生成可以邮寄到列表的 mbox 格式文件,它将每个提交转换为一封电子邮件,提交信息第一行作为主题,剩余信息与补丁作为正文:
git format-patch -M origin/master
# 生成补丁文件
# <file-name>.patch
# <file-name>.patch你可以将补丁文件粘贴到电子邮件客户端,或通过命令行程序发送:
# 本地邮件服务器设置正确的前提下,使用此命令
git send-email <file-name>.patch5. 维护项目
除了参与项目贡献,也需要了解维护者视角:接受别人提交的补丁、整合远程分支、判断历史是否清晰、决定什么时候合并。
主题分支工作
如同在本地新建特性分支一样,在添加贡献者的提交分支并通过本地测试后,再考虑是否将其合并到长期分支中。这是管理并行开发的基本方法。
合并工作流
最基本的工作流是将所有工作直接合并到 master 分支。master 分支包含的代码应保持基本稳定。当你完成某个主题分支的工作或审核通过其他人的贡献后,将其合并入 master,然后删除主题分支,如此循环。
对于大型项目,可以采用多长期分支策略。例如 Git 项目使用 master、next、pu(建议更新)和 maint(维护性向后移植)四个分支,主题分支先合并到 next 进行测试,确认稳定后再进入 master。
变基与拣选工作流
为了保持线性的提交历史,有些维护者更喜欢在 master 分支上对贡献的工作进行变基(rebase)和拣选(cherry-pick),而不是直接合并。在主题分支上运行变基命令,可以在当前 master 分支的基础上重新构造修改,使提交历史更加清晰。
6. 协作原则
协议选择看身份和环境:HTTPS 通用、穿透性好;SSH 适合开发者日常写权限;匿名 Git 协议今天很少作为主线。企业网络、凭据管理和审计要求会影响选择。
PR 是讨论单元,不只是合并按钮:好的 PR 说明动机、范围、风险和验证方式。提交历史服务审查,不服务个人炫技。
Fork 适合权限隔离:开源项目用 Fork 保护主仓库写权限;组织内部项目也可以用分支权限、CODEOWNERS 和 CI 达到类似效果。
维护者关心可合并性:变更越小、历史越清楚、测试越明确,越容易被接受。大型改动先开 Issue 或 Draft PR,减少方向性返工。
共享历史要慎改:远程协作的底线是不要让别人基于的历史突然消失。需要强推、重打标签、清理历史时,先沟通。
了解远程协作后,再配置 Git 环境和增强工具,才知道哪些效率提升是为协作服务,哪些只是个人偏好。