关于 Git 工作流,我之前只知道有个 Git Flow。工具我没有用过,不过思路我很赞同。类似 Git 这样的分布式版本控制,不再强调代码在提交时的整合,而是强调中心库向私有库的分裂和各个私有库各自的合并。分支越细致,合并代码的成本就越低。以 Feature、Bugfix 为单位整理分支,合并的时候就会非常清晰。如果代码耦合度低的话,几乎所有合并都可以自动完成。
这次在学校和同学一起开了一个 Web 项目,代码用 Git 来管理。参与的同学之前只用过 SVN,对 Git 也是初次接触。我考虑要不要尝试一下 Git Flow 这个工具,所以在豆瓣发了一条广播,结果几位同学回复让我看到更多类似 Git Flow 的工具或者思路,所以写篇文章记录下。本文纯属记录,没有主题。
Git 实践
主干分支永远可用
The master branch should be deployable in anytime.
我看到 GitHub 上非常多项目都遵守这一做法。我不清楚这么做的其他好处,只是将其理解为一种共同的约定——从任何一个遵守这一约定的仓库 checkout 出代码,master 分支一定不是在开发了一半的“施工中”状态。这一点在非分布式版本控制中也可以看到。清风老师在 BPUG 的一次会课提到过,豆瓣的主站代码用 SVN 托管,所有开发者都把 trunk 复制到一个以自己名字命名的分支下(我觉得这很类似于 GitHub 的 Fork),开发者完成开发后再合并到 trunk 。这样 trunk 的代码也是可用的。其他人需要开新的分支时,可以方向地从 trunk 或者 master 开始创建;类似 rebase 这样的动作,也可以很方向地把目标瞄准 master 。
在 Git Flow 的方式中,有个 release 分支保存发行的点。我觉得这个可以用 master 分支来替代,而且这个很适合用 master 分支来替代,因为这样可以确保我们不把没打上发行 Tag 的提交合并到 master 。
细粒度分支
“尽情开分支,切分支,rebase merge 效率比SVN高出很多”
这句是巨句同学说的。我在阅读《Pro Git》的时候书上也提到过,Git 鼓励多用细粒度分支,对此也做了高度优化。
我此前用 Git 有两种用法,一种是确定从头到尾只有我一个人开发的时候,我会只使用 master ,然后一条直线提交到最后。但是来实习之后,我写的第一份代码就改变了这种用法。因为之前的一些开发工作我发现,即使只有一个人开发,也难免会遇到需要 branch 的时候。
比如已经发行了 0.1 版本,正在为 0.2 版本开发一个 feature 的时候,我突然遇到 0.1 版本的一个 bug。为了修复这个 bug,无论是写 hotfix 还是发行 0.1.1 版本,都是会打断当前工作的。如果我使用分支来完成这个工作,我可以从 master 中打 0.1 tag 的地方开始创建一个 hotfix 分支。
对比起来,git 的 branch 和 SVN 或 HG 的分支含义不同,前者的分支是一种类似平行空间的概念。目录、文件还是原来的目录、文件,但是它停留在历史上的某个点了。如果继续发展下去,不同的分支也会走不同的路线,就像两个完全独立的版本仓库。所以从 0.1 的 hotfix 到 0.1.1 的发行,对 0.2 可以不造成任何干扰。
关于工具
Git Flow 这类工具似乎是想在工作流的层面上屏蔽 Git 操作的底层细节,其实我个人不是很赞同这样做。我觉得版本控制是一件比项目管理更加细致的事情,它可以细致到每一行源代码。现有的 Git 操作让我觉得粒度刚好合适,既不繁琐,又清晰明了。如果我需要开启一个 Feature,我可以非常清晰地完成每个步骤:
但是如果上述步骤全部变成了
我会觉得很没有安全感。如果一切都在预期之内,那么这类工具能方便工作。但是如果发生某些异常情况呢?我可能连 Git Flow 做了什么都不知道,不像 Raw Git 时候我会清晰地记得自己刚刚执行了 git merge 。
现在的关键问题是,对于这个问题我没有什么发言权,因为我自己没有真正用过 Git Flow 或者其他类似工具。所以希望用过的同学如果有想吐槽的能吐出来…… 讲解 Git Flow 便捷的文章能看到很多,但是貌似和官网的说法没有大的区别。我个人还是更期待吐槽文。
其实我也可以就试用一下,我想尝试下新鲜事物总是好的,最坏的结果是又挖一个坑罢了。从 IDE 使用者到 Sublime Text 使用者再到最近刚刚上手 Vim 并感叹 Vim 的强大,期间也不经意尝试了很多新鲜事物。
另外 xx 同学推荐了两款类似的 GitHub 工作流解决方案,这里也记录一下:GitHub Flow 和 legit。