约定Git规范
每个人都应当遵循对于分支命名、标记和编码的规范。每个组织都有自己的规范或者最佳实践,并且很多建议都可以从网上免费获取,而重要的是尽早选择合适的规范并在团队中遵循。
同时,不同的团队成员的 Git 水平参差不齐。你需要创建并维护一组符合团队规范的基础指令,用于执行通用的 Git 操作。
Commitizen 是一个格式化 commit message 的工具。简而言之,git commit 就是你在做一次修改后类似于写一个备注,现在 npm 安装了commitizen 后,你可以使用 git cz 取代 git commit,每次提交的时候可以选择本次 commit 的类型,这样 commit 的文本会更具有可读性。
正确合并冲突
每个团队成员都需要在一个单独的功能分支上开发。但即使是使用了单独的分支,每个人也会修改一些共同的文件。当把更改合并回 master 分支时,合并通常无法自动进行。可能需要手动解决不同的人对同一文件不同变更的冲突。这就是你必须学会如何处理 Git 合并的原因。
现代编辑器具有协助解决 Git 合并冲突的功能。它们对同一文件的每个部分提供了合并的各种选择,例如,是否保留你的更改,或者是保留另一分支的更改,亦或者是全部保留。如果你的编辑器不支持这些功能,那么可能是时候换一个代码编辑器了。
使用 git rebase 合并冲突,这意味着要经常执行以下步骤:
git pull --reabase origin master
// 改完冲突后重新提交代码
git add .
// 重新提交不要写提交信息
git rebase --continue
// 退出
git push origin feature-todo -f
// 再次提交到远端需要强推
这些步骤会在你的功能分支上重写历史(这并不是件坏事)。首先,它会使你的功能分支获得 master 分支上当前的所有更新。其次,你在功能分支上的所有提交都会在该分支历史的顶部重写,因此它们会顺序地出现在日志中。你可能需要一路解决遇到的合并冲突,这也许是个挑战。但是,这是解决冲突最好的时机,因为它只影响你的功能分支。
如果使用“纯合并”策略(git pull origin master),那么 master 分支的历史将穿插着所有同时开发的功能的提交。这样混乱的历史很难回顾。确切的提交时间通常并不是那么重要。最好是有一个易于查看的历史日志。
合并多个message
当你在功能分支上开发时,即使再小的修改也可以作为一个提交。但是,如果每个功能分支都要产生五十个提交,那么随着不断地增添新功能,master 分支的提交数终将无谓地膨胀。通常来说,每个功能分支只应该往 master 中增加一个或几个提交。为此,你需要将多个提交的 message 合并成一个或者几个带有更详细信息的提交。通常使用以下命令来完成:
git rebase -i HEAD~20
// 合并20个提交
git commit --amend
// 编辑完之后执行退出
最后,由于重写了分支的 Git 提交历史,必须强制更新远程分支。
使用标签
当你完成测试并准备从 master 分支部署软件到线上时,又或者当你出于某种原因想要保留当前状态作为一个里程碑时,那么可以创建一个 Git 标签。对于一个积累了一些变更和相应提交的分支而言,标签就是该分支在那一时刻的快照。一个标签可以看作是没有历史记录的分支,也可以看作是直接指向标签创建前那个提交的命名指针。
git tag v1.0.0 -m "1.0.0版本"
此外,如果带签名的 tag 有助于你的项目,可以考虑使用它们。
考虑这样一种情况:Git 标签对应的软件版本已经分发给客户,而客户报告了一个问题。尽管代码库中的代码可能已经在继续开发,但通常情况下为了准确地重现客户问题以便做出修复,必须回退到 Git 标签对应的代码状态。有时候新代码可能已经修复了那个问题,但并非一直如此。通常你需要切换到特定的标签并从那个标签创建一个分支:
git checkout v1.0.0
// 切换到分发给客户的标签
git checkout -b bugfix-todo
// 创建新的分支用于重现 bug
Git 是一个需要花时间去掌握的复杂工具。使用这些实践可以帮助团队更好的使用 Git 协作开发。