与他人协作是 Git 的核心价值所在。远程仓库不是“云端备份”,而是团队共享历史、审查变更和发布版本的协调点。理解远程协作,重点不是背协议,而是知道什么身份能写、什么历史能改、什么变更需要审查。

1. Git 传输协议

Git 使用四种不同的协议来传输数据:本地协议、HTTP(S)、SSH 和 Git 协议。

协议传输方式优点缺点适用场景
本地协议文件系统路径简单、无需网络无权限控制本地备份
HTTP(S)HTTP/HTTPS穿透防火墙、广泛支持效率略低通用场景
SSHSSH 隧道安全、高效需配置密钥开发者日常
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 允许多个远程仓库存在,每个开发者拥有自己仓库的写权限和其他人仓库的读权限。通常有一个代表”官方”项目的权威仓库,贡献流程如下:

  1. 项目维护者推送到主仓库。
  2. 贡献者克隆此仓库,做出修改。
  3. 贡献者将数据推送到自己的公开仓库。
  4. 贡献者给维护者发送邮件,请求拉取自己的更新。
  5. 维护者在本地仓库中将贡献者的仓库添加为远程仓库并合并修改。
  6. 维护者将合并后的修改推送到主仓库。

主管与副主管工作流

这是多仓库工作流的变种,适合拥有数百位协作开发者的超大型项目(如 Linux 内核)。副主管(lieutenant)负责集成项目的特定部分,主管(dictator)作为总集成者统筹全局:

  1. 普通开发者在自己的主题分支上工作,并根据主管的 master 分支进行变基。
  2. 副主管将普通开发者的主题分支合并到自己的 master 分支中。
  3. 主管将所有副主管的 master 分支并入自己的 master 分支中。
  4. 主管将集成后的 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>.patch

5. 维护项目

除了参与项目贡献,也需要了解维护者视角:接受别人提交的补丁、整合远程分支、判断历史是否清晰、决定什么时候合并。

主题分支工作

如同在本地新建特性分支一样,在添加贡献者的提交分支并通过本地测试后,再考虑是否将其合并到长期分支中。这是管理并行开发的基本方法。

合并工作流

最基本的工作流是将所有工作直接合并到 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 环境和增强工具,才知道哪些效率提升是为协作服务,哪些只是个人偏好。