# 分支管理

git-branch

# 基本原则

一个项目 Git 初始化后,会生成一个主干分支,通常叫 master(部分会叫 main),然后也会人为创建一个叫 dev 的分支,用于开发。

那么,基于 Git 项目开发时,应准守以下的一个基本原则:

  1. master分支应该保持稳定,并随时可用于发布,且不可在该分支上直接进行开发;
  2. dev分支是不稳定的,开发完成某个功能并测试通过后,再合并回主干。

初始或者较小项目也需要这样吗?

项目在开始之初,可以不拉出dev分支,如果涉及到多人合作开发,同样需要拉出各自分支进行开发,然后保持一个适当的合并时机。

# 命名规则

# 日常开发

日常项目开发过程中,往往就两个事情:新需求开发或问题修复。一个好的开发习惯,就是基于目标分支,checkout 出一个临时分支,进行开发或问题修复,请按照以下命名规则进行分支创建。

{类型}/{目标分支}/{任务描述}

# 如:
feat/2.0.0/test
  • 类型:包括featfix等,这不做强制要求;
  • 目标分支:就是被检出分支的名称;
  • 任务描述:简单描述任务内容。

此类分支属于临时分支,除非任务需要的开发时间较长,否则不应该推送分支到远程仓库,并且在任务完成后,合并回目标版本,然后删除(若分支已推送到远程仓库,同样需要删除)。

# 版本发布

通常在项目即将上线前,会进行代码封版,也就是所有新功能都已经在 dev 分支上。此时,需要在 dev 分支上,检出一个预发布的临时分支,步骤如下:

  1. 在 dev 分支检出预发布的临时分支,命名为{发布版本}-SNAPSHOT,如 2.1.0-SNAPSHOT;
  2. 预发布分支,在没有特殊的情况下,不可修改,若临时发现bug,需要多方评估后,再决定是否在预发布分支上进行修改;
  3. 最终以预发布分支进行版本发布,发布成功后,将分支合并到主干和 dev 分支,优先使用 rebase(变基);
  4. 在主干分支打上 tag,命名为{发布版本},如 2.1.0(无需加 v 字母开头);
  5. 删除临时发布分支。

为何需要在 dev 上再检出一个临时发布分支?

一般从封版到正式发布,可能会有1-2天的时间间隔,那不可能所有人都停下工作。检出一个预发布版本分支,就是为了可以继续基于当前 dev 分支进行开发。但请注意,任何开发工作,从 dev 分支检出后,在版本发布成功前,不应合并回 dev 分支。

# 定制分支

在产品开发过程中,难免会有部分客户需要大量的定制功能,此时,通常需要拉出一个特定的分支,例如:某客户需要在 2.1.0 版本上,加入定制功能,则需要检测以{特定版本}-{客户名}的分支。

  • 特定版本,就是客户需要加入定制需求的分支;
  • 客户名,客户公司或者集团的英文简写名称,统一使用小写英文字母加下划线组成,如 2.1.0-workplus_lite。

定制需求分支的日常开发和版本发布,都应遵循上面的日常开发版本发布规范,同时也应该检出一个开发分支,如 2.1.0-workplus_lite-dev。

什么情况下适合检出定制分支?

客户的定制需求,通常需要经过产品的评审,再决定是否需要产品化,此外,如果定制功能的量不多,或者只是某些行为会有差异,则可以通过配置文件进行开关控制即可。毕竟分支检出后,会产生更多的维护成本,在可不检出定制分支的情况下,优先不检出。

# 代码合并

rebase 和 merge:

rebasemerge都可用于合并分支,但请优先使用rebase

  • rebase 操作可以把本地未 push 的分叉提交历史整理成直线;
  • rebase 的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

cherry-pick:

Git 提供cherry-pick命令,允许复制一个特定的提交到当前分支,非常适合用于多分支项目的代码合并或功能迁移。此外,cherry-pick是会产生一个新的提交记录,虽然提交的内容是一样的,对项目的提交历史链起到一个很好的维护作用。

stash:

在日常开发过程中,可能需要临时去修复某个分支上的 bug,但是又不想放弃或提交未完成的工作,此时可以使用 Git 的stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

$ git stash
Saved working directory and index state WIP on dev: f86ae33 add merge

问题修复完成回到开发分支时,可以通过git stash list查看工作现场,并且可以用以下两个方法进行恢复:

  1. git stash apply恢复,但是恢复后,stash 内容并不会删除,你需要用git stash drop来删除;
  2. git stash pop,恢复的同时把 stash 内容也删除。

# 在线教程