git workflow
讲一下常用的 workflow,这个主要是根据自己个人工作经验,每个项目在实践上总会有些许的不同,求同存异。
单分支工作
最糟糕的 workflow 是所有人全都在 main/master 上干活,如果只是两三个人的 team 可能还能存活,但是如果工作的人数比较多的话,挺麻烦的……
第一点是成本,因为一些项目可能会继承了一些 CI/CD 的东西,每一次推送到主分支上都会引起 CI/CD,有一些的 pricing tier 上是按照重部署多少次收钱,因此可能会造成额外的成本。
第二点可能会破坏某个环境,假设你的 main 绑定了开发环境,如果有一些本地的变化使得这个分支没法运行了,那么就会直接搞得开发环境也无法运行。如果没有开发只有生产,那么就会造成项目停摆,客户无法继续使用产品。
第三点就是非常难以管理,有一些团队(比如说我之前的团队)会要求所有的人在每天结束的时候 commit 自己的变化,假设这里只有一个分支,下班时间大家都抢着往一个分支上推东西,那么可以想象一下每一次往上推都会因为 remote changes 被拒绝,拉下最新的代码又要修 merge conflicts 有多烦。
第四点就是这也非常的开发不友好,假设说某位开发有一些修改不是很确定,那么 ta 需要把当前不工作的版本推上云端去询问一下意见,这种情况下主分支肯定是没办法运行了,第二天别人来拉最新的代码,那么本地的版本也会不工作。
最后也就是新功能的开发,哪怕就是单人的项目,如果想要测试一些新的功能,或者是进行版本的迭代,仅仅在一个分支上工作也是非常难以满足需求的。
多分支协作
这也是常见的工作流方式,每一个子分支可以代表一个功能(feature),等到整个子分支实现之后,再将子分支合并到 main/master 上,如:
---
title: Example Git Branch Workflow
---
gitGraph
commit
branch feature
commit
branch feature2
checkout feature2
commit
commit
checkout main
merge feature
commit id:"deploy 4d89eb17" tag:"release"
checkout feature2
commit
checkout main
merge feature2
commit id:"deploy ed34b75f" tag:"release"
主分支上负责两个功能:
- 合并已经实现的功能
- release
这样能够有效的解决前面提到的几个问题,并且,如果当前合并的功能可能会导致一些功能无法使用,这个 workflow 能够很快地回滚到上一个工作的版本。
合并分支
最暴力的做法就是直接 merge 到 main 分支上,如 git merge <branch-name>
,然后推上去。但是在企业开发环境,这种事情是要禁止的 ❌
正常来说合并分支的做法是提一个 Pull/Merge Request,在群组里发个消息让对应的同事 review 一下。这个过程每个平台其实都不太一样呢,原因大概是因为 PR/MR 这个是每个平台自己实现的。
依旧之前做 demo 的 repo 为例,这里已经有了好几个 branch:
这时候我就可以切换到 Pull Request 下面:
点击 New PR
,再选择对应的分支进行 PR,然后平台就会对比两个 branch 之间的差异:
如果可以 fast forward,那么 git 就会显示 able to merge 的标记,否则就会让人修复一下 merge conflict 再继续:
当别的同事过来看 PR 的时候,如果同意你的 PR,就可以选择直接 merge,否则也可以留下评论回复一下问题所在,交换意见,最后修改完再 merge:
我找了个有 conflict 的例子,大概就是这样的:
这个情况下不修复 conflict 的话,github 会阻止用户 merge 进去。
branch protection
branch protection 也是在 repo 的 settings 下面可以设置的,制定了 rule 之后可以防止别人使用 git push -f
强行将变化推到保护的分支上,或是删除主分支:
如果是比较大的项目,就可以设置不同的 patterns,比如说除了 main
这个固定分支外,有可能所有在 release/
下面的也不能删除,或是其他的环境 qa/
等。
其他一些设定就是包括 PR 必须要被 review 等,下面就加了一个 PR 必须要被 review 的规定,于是之前的 PR 就被 block 了:
fork
clone 是将项目克隆到本地,但是远程的 reference 还是原始的项目。fork 会将项目 clone 自己的账户下,这样就有了不同的 repo。
我个人倒是没试过 fork open source 的项目,不过 fork 完了项目之后,还可以提 PR,将自己的变化推回原本的项目中。
我倒是没什么 forked 的项目,不过 UI 上会有一些提示,然后问你要不要做 PR,所以这里就多嘴提一句了。