《精通git第二版》读书笔记·ch05 git的分布式工作流程
git的分布式协作可以衍生出不同的工作流程,主要有以下几种:
集中式工作流,即单点协作模型。若干个开发者将自己的工作与仓库进行同步,类似于中心与节点的关系。如果两个开发者同时做了修改,那么第一个开发者推送回服务器后,第二个开发者需要先将第一个人的工作合并进来。
集成管理者工作流。每个开发者有自己仓库的写权限、其他仓库的读权限。例如github的PR。首先从“官方”仓库克隆一个自己的公开仓库,将修改推送上去,然后请求官方仓库的维护者拉取更新。维护者可以将公开仓库作为远程仓库,在本地测试变更,然后合并到分支中,推送到“官方”仓库。基本流程如下:
- 维护者推送到主仓库。
- 贡献者克隆主仓库,作出修改,推送到自己的公开仓库。
- 贡献者请求拉取更新。
- 维护者在本地仓库合并修改。
- 维护者将修改推送到主仓库。
司令官与副官工作流。副官(lieutenant)作为集成管理者,负责集成项目中的特定部分。司令官(dictator)作为总集成管理者,负责统筹,其维护的仓库作为参考仓库。这种流程一般用于庞大复杂的项目,或者多级别管理。流程如下:
- 普通开发者在特性分支上开发,根据参考仓库的master分支进行变基。
- 副官将普通开发者的特性分支合并到自己的master分支。
- 司令官将副官的master分支合并到自己的master分支。
- 司令官将集成后的master分支推送到参考仓库中,用于开发者以此进行变基。
提交准则
好的提交准则会让协作更加容易。
在git源代码的Documentation/SubmittingPatches
文件中列举了创建提交补丁的建议。注意以下几条:
- 不要把空白错误提交上去。可以用
git diff --check
检查。 - 让每一个提交成为一个逻辑上的独立变更集,让改动可以理解,让审查更容易。可以用
git add --patch
部分暂存文件。 - 提交信息。应当以少于50个字符(25个汉字)的单行开始,简要描述变更。空行,接一个详细的解释。git项目要求更详细的解释,包括改动的动机和实现方式与之前的区别。信息中最好使用祁使语气,即动词开始。
向项目贡献代码
向项目做贡献的方式有很多,影响因素有活跃贡献者的数量、使用的工作流程、提交权限等。
私有小型团队。只有1-2个开发者的私有项目,可以采用集中式工作流。例如在特定分支上工作,合并回master。如果origin/master有合并,则合并后提交。参考原书的例子。
私有管理团队。采用整合-管理者流程,独立小组的工作只被特定的工程师整合,主仓库的master分支只能被特定工程师更新。所有工作都是基于团队的分支上完成,稍后被整合者拉到一起。参考P122。
派生的公开项目。使用git托管网站上的派生功能来协作,建议始终维持一个跟踪origin/master
的master
分支。基本流程如下:
- 首先克隆主仓库,创建特性分支,贡献代码。
- fork原始仓库,添加为第二远程仓库,将特性分支推送到仓库中。
- 通知维护者,开启pull request。
通过邮件的公开项目。使用git format-patch -M origin/master
生成mbox格式补丁文件。用git imap-send
将补丁序列放到IMAP服务器的Drafts文件夹中,或者git send-email
发送补丁序列。需要在git config
中配置email信息。
维护项目
需要同其他贡献者约定某种长期可持续的工作方式。
如果想整合一些新东西,最好在特性分支中工作。
应用来自邮件的补丁,流程如下:
- 对于使用
git diff
或Unix diff
创建的补丁,使用git apply "xxx.patch"
来应用,采用了全部应用否则全部撤销的模型。运行后,手动暂存并提交。可以添加--check
参数检查是否可以顺利应用。 - 对于
format-patch
生成的补丁,使用git am "xxx.patch"
来应用补丁,并自动创建提交。如果发生冲突,则需要手动解决后添加--resolved
参数继续运行。
检出远程分支。贡献者建立了自己的版本库,并推送了修改。维护者可以将其添加为远程仓库,创建远程分支,并在本地合并。对于频率低的合作,可以使用git pull "xxx"
一次性抓取数据。
确定引入的内容。一般来说,需要对特性分支中含有但master没有的提交进行检查。git log "xxx" --not master
可以显示特有的提交。如果要查看特性分支和另一个分支合并后的差异,可以使用git diff master..."xxx"
来比较。
在整合内容时(合并特性分支),需要考虑项目维护的总体工作流程。有以下几种方式:
- 合并工作流。特性分支合并到master分支后,删除特性分支。如果项目重要,考虑两阶段合并,维护master和develop两个长期分支,master分支在非常稳定的版本发布时更新,develop分支用于合并新的特性分支。打标签发布时,将master分支合并到develop分支。也可以使用整合分支来专门整合,之后合并到develop和master分支。
- 大项目合并工作流。git项目包含master、next、pu(proposed updates)、maint(维护向后兼容)4个长期分支。对于特性分支,进行测试评估,安全后合并到next分支,然后推送给所有人。如果特性分支需要更多工作,则合并到pu分支,稳定后再次并入master分支。
- 变基和拣选工作流。整合特性分支时,可以在该分支上应用变基,在目标分支上进行重新构造。拣选类似于对某个特性提交的变基。
- Rerere(?)。重用已记录的冲突解决方案,开启后git维护一些成功合并前和后的镜像,发现之前处理过类似的冲突时,自动使用之前的方案。
git config --global rerere.enabled true
来开启,同时可以用git rerere
命令与缓存交互。
为发布打标签。维护者应该为发布打附注标签。命令为git tag -s v"xxx" -m "xxx"
。对于分发签名用的PGP公钥,可以以blob对象存储在git仓库中。
1
2
3
4
5
gpg --list-keys
gpg -a --export "XXX" | git hash-object -w --stdin
git tag -a maintainer-pgp-pub "sha-1xxx" # 打tag
git show maintainer-pgp-pub | gpg --import # 导入
生成构建号。用git describe
可以用提交附加一个可读的名称,只适用于有注解的标签。
准备发布。用git archive "xxx" --prefix="xxx/" | gzip > $(git describe master).tar.gz
,创建一个快照归档。
制作提交简报。git shortlog
命令可以快速生成自上一次发布之后新增内容的修改日志类文档。
参考
《精通git第二版》