Git 基础与工作流

前期工作

  • 对Git基本命令有个初步的了解,本篇博客不对基本命令一一解释,推荐学习廖雪峰的Git教程

  • 配置SSH KEY,这一点比较容易被人遗忘。当然如果你不嫌麻烦用Https每次都输入账号密码的话,请忽略这一点。

为什么远程仓库需要SSH Key呢?因为远程仓库需要识别出你推送的提交确实是你推送的,而不是别人冒充的,
Git支持SSH协议,所以,远程仓库只要知道了你的公钥,就可以确认只有你自己才能推送。
当然,远程仓库允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到远程仓库,就可以在每台电脑上往远程仓库推送了。

创建远程仓库并与本地仓库关联

Git 基础与工作流
流程图

创建远程仓库

在开发过程中,我们的master 分支通常用于迭代上线版本,例如1.0.0,1.1.0,2.0.0等等,所以我们将 master 分支设为保护分支,避免开发人员往master分支推代码。在创建远程仓库的时候,建议添加Readme.md文件初始化仓库,此时会自动生成master分支,我们就可以将master分支设置为保护分支了。

创建本地仓库

在将一个项目进行版本管理之前,我们会通常在一个空的文件夹内创建项目或在AndroidStudio直接新建一个项目(AndroidStudio - New Project),完成基础配置、依赖添加之后,才会初始化git仓库进行管理(注意将不必跟踪的文件添加进.gitignore)

  • 第一步:初始化git仓库

    $ git init
    
  • 第二步:关联远程仓库

    $ git remote add origin git.XXXXXX(ssh/https)
    
  • 第三步:拉取远程仓库

    $ git pull origin master
    

    此时我们就将之前创建的Readme.md文件拉取下来了。这样才算真正的与远程仓库同步。

  • 第四步:创建并切换分支

    $ git checkout -b develop
    

    develop 分支是我们的开发分支,一般在完成小的功能节点后再推送到远程仓库上。在创建并切换到develop分支之后,工作区内保存着最新的未添加到暂存区的代码。

  • 第五步:添加更改并提交

    $ git add . (再次提醒:.gitignore忽略不必要跟踪文件)
    $ git commit -m"init project"
    
  • 第六步:推送到远程仓库

    $ git push -u origin develop
    

    尽管我们不能将代码推送到master分支,但是新建分支并将该分支推送到远程仓库是不受限制的。当我们需要上线并合并到master 分支时,我们可以创建一个pull request完成合并。

多人协作开发

Git Flow工作流

Git Flow工作流是 Vincent Driessen 2010 年发布出来的他自己的分支管理模型,到现在为止,使用度非常高。

Git Flow 的分支结构很特别,按功能来说,可以分支为5种分支,从5 种分支的生命时间上,又可以分别归类为长期分支和暂时分支,或者更贴切描述为,主要分支和协助分支。

主要分支:

在采用 Git Flow 工作流的项目中,代码的*仓库会一直存在以下两个长期分支:

  • master
  • develop

其中 :

  • origin/master 分支上的最新代码永远是版本发布状态。
  • origin/develop 分支则是最新的开发进度。

当 develop 上的代码达到一个稳定的状态,可以发布版本的时候,develop上这些修改会以某种特别方式被合并到 master 分支上,然后标记上对应的版本标签。

协助分支:

除了主要分支,Git Flow 的开发模式还需要一系列的协助分支,来帮助更好的功能的并行开发,简化功能开发和问题修复。是的,就是下面的三类分支。这类分支是暂时分支非常无私奉献,在需要它们的时候,迫切地创建,用完它们的时候,又挥挥衣袖地彻底消失。
协助分支分为以下几类:

  • Feature Branch
  • Release Branch
  • Hotfix Branch

Feature 分支用来做分模块功能开发,命名看开发者喜好,不要和其他类型的分支命名弄混淆就好,举个坏例子,命名为 master 就是一个非常不妥当的举动。模块完成之后,会合并到 develop 分支,然后删除自己。

Release 分支用来做版本发布的预发布分支,建议命名为 release-xxx。例如在软件 1.0.0 版本的功能全部开发完成,提交测试之后,从 develop 检出release-1.0.0 ,测试中出现的小问题,在 release 分支进行修改提交,测试完毕准备发布的时候,代码会合并到 master 和 develop,master 分支合并后会打上对应版本标签 v1.0.0, 合并后删除自己,这样做的好处是,在测试的时候,不影响下一个版本功能并行开发。

Hotfix 分支是用来做线上的紧急 bug 修复的分支,建议命名为 hotfix-xxx。当线上某个版本出现了问题,将检出对应版本的代码,创建 Hotfix 分支,问题修复后,合并回 master 和 develop ,然后删除自己。这里注意,合并到 master 的时候,也要打上修复后的版本标签。

Merge 与 --no-ff 参数

需要说明的是,Git Flow 的作者 Vincent Driessen 非常建议,合并分支的时候,加上 no-ff 参数,这个参数的意思是不要选择 Fast-Forward 合并方式,而是策略合并,策略合并会让我们多一个合并提交。这样做的好处是保证一个非常清晰的提交历史,可以看到被合并分支的存在。

Git 基础与工作流
no-Fast-Forward与Fast-Forward对比

从上图可以看到,Feature 分支上的三个节点不选择Fast-Forward的方式合并,依然保留了Feature的提交历程,节点流动清晰、容易追溯。

GitFlow 工作流示意图

Git 基础与工作流
理想的Git网络

图中画了 Git Flow 的五种分支,masterdevelopfeature branchs,release branchs , hoxfixes,其中 mastedevelop 字体被加粗代表主要分支。master 分支每合并一个分支,无论是 hotfix 还是 release ,都会打一个版本标签。通过箭头可以清楚的看到分支的开始和结束走向,例如 feature 分支从 develop 开始,最终合并回 develophoxfixesmaster 检出创建,最后合并回 developmastermaster 也打上了标签。

工作流程

了解以上概念,我们接着之前创建的仓库继续捣鼓。

Git 基础与工作流
多人协作开发流程
  • 第一步:基于develop 新建一条Feature 分支。

    $ git checkout -b myfeature develop
    Switched to a new branch "myfeature"
    
  • 第二步:啪啦啪啦 敲代码完成某部分功能并提交

    Complete some function
    
    $ git add .
    $ git commit -m"ok"
    
  • 第三步:切回到develop 分支,同步远程分支(git pull)

    $ git checkout develop
    $ git pull origin develop
    
  • 第四步:将Feature 分支合并至develop 分支

    $ git merge --no-ff -m"merge" myfeature
    
  • 第五步:解决冲突,add and commit.(如果没有冲突则忽略该步骤)

    Resolve Conflicts
    
    $ git add .
    $ git commit -m"fix bugs"
    
  • 第六步:将develop分支 推送至远程仓库

    $ git push origin develop
    
  • 切换至Feature 分支,HEAD 指向develop分支的最新节点(同步)

    $ git checkout myfeature
    $ git rebase develop
    

    因为前面develop分支主动合并了Feature分支并解决了冲突,所以这一步不会出现任何异常,如果出现异常请检查前面的步骤是否正确。

  • 将Feature分支 推送至远程仓库

    $ git push origin myfeature
    

至此,以上步骤可以处理绝大部分协同开发的情况