Git && Git Flow 使用总结

前言

在前公司的时候用的是SVN,Git只是自己平时在github写点东西的时候用一下,也没太认真,来到这边后就用起了Git。虽然这边iOS只有我一个人,但还是在用了Git一个月后,自己用起了Git Flow,并尽量按照流程走,现在用Git Flow也差不多一个月了,正好昨天项目上线了,今天事少点,外面下着小雨是个写东西的好时机,做个小小的总结。

Git

不用做过多介绍,Git早已为程序员大众所知,一般新点的互联网公司都用Git进行版本管理了。我仅以上家公司一年多的SVN使用经历讲一下Git的优势。

  • 分布式 && 版本库

    在众多介绍SVN和Git区别的文章里,分布式应该是提的最多也是必提的一点。用SVN的时候程序是集中存放在服务器中,开发人员下载代码到自己的电脑上,没有网络时看不到版本记录无法commit。Git是将完整的版本库(版本记录和代码)存放在各个用户的电脑上,就算没有网络或者服务器坏了,也能在本地进行commit,等服务器和网络好了再push上去就行了。

    说到这里我想Git的优势已经很明显了--使用受网络的影响不太大。我在上家时服务器是在深圳那边的分公司的,有一次我们上海这边因为有bug要回滚的时候那边的服务器出了问题,我们拉不到版本记录,没法回滚,只能干等他们修复服务器后再进行回滚。用Git的话在本地就可以看到History Commit,找到对应的进行回滚就OK了

  • 存储方式

    很多博客文章都是说Git基于元数据,SVN基于文件,我是不大懂元数据这个概念,就用自己的理解说一下。

    直白地看就是Git管理的工程只在根目录(相对工程来讲)有一个.git文件,所有的版本、commit、tag、branch等信息都在这里,管理起来非常方便;SVN是每一个文件都有一个.svn文件,管理起来还是有点麻烦的,此外当你像一个目录的几个文件忽略的时候设置起来也是相当麻烦。

  • 分支

    这个本事打算放在上面写的,想了想还是独立出来吧。在SVN的体系里,一个分支就是一个单独的目录,是对全部代码的拷贝,最后服务器都是分支;在Git里所有的分支信息都是在.git里,可以在本地创建分支,服务器只留develop、master等少数几个分支。

    有可能是我们当时没用好,在上家公司的时候,发生了几次合并时文件缺失的问题,最后基本都是新建一个分支,完成测试后,用Xcode 的 File Merge比较两个工程的目录,合并生成新的文件覆盖就有文件,以这样的方式进行合并,改动大的一次合并了一天。

    现在使用Git,开发新的功能的时候切换到新的分支,完成测试后直接merge,轻松了很多,基本没出过这些问题。而且有时自己像做些测试,可以直接切个新分支出来,随便改,对别人没什么影响,测试完觉得不用动的话直接删掉这个分支。

Git简单入门

本来没想写这个的,只是想总结使用经验,不是写教程。不过像是不受控制一样,这样的章节就到脑海中来了,简单写一个Git的入门指令吧。

1、创建仓库
cd到工程目录(应该是空的),执行

git init

不过我们一般是不需要自己创建的,多半是公司服务器已经有仓库了,我们直接在工程clone下来就行。

git clone username@host:/path/to/repository

2 开始工作
仓库设置好就可以开始工作了,先查看一下分支情况

git branch          //  查看本地分支
git branch -r       //  查看远程分支

选择(创建)分支工作

git checkout -b feature_x       //  创建一个feature_x分支
git checkout master             //  切换到master分支
git pull                        //  早上起来先拉一下代码

测试完成后提交代码

git add <filename>              //  添加指定文件
git add *                       //  添加所有文件
git commit -m "代码提交信息"    //  提交

推送到服务器

git push origin master          //  推送到服务器的master分支中
git remote add origin <server>  //  如果上面创建时,没有服务器仓库,这里就要连接仓库了

一切OK后删除本地分支

git branch -d feature_x         //  删除feature_x分支

以上只是一个简单的Git入门介绍,有很多东西都没讲,一时也讲不完,很多人推崇命令行,不过我觉得入门的时候用GUI工具更合适,容易适应,出错率也会相对低一些。Sourece TreeTower都不错。

Git Flow

上面说了那么多Git的好处是不是就是说Git没有坏处了呢?至少对我来讲答案是否。

正是上面说的存储方式的优点,让开发人员容易在分支切换和合并中糊涂--毕竟有那么多分支。

所以各大公司都会规定自己的Git工作流程,比如先pull或者fetch或者pull -rebase,然后stash,怎么新建feature,怎么merge,谁来删除等等,就是为了减少分支切换、合并过程中出错。

而在其中最著名的流程应该就是Git Flow了。

Git Flow流程,我就借用这张在网上广为流传的图了

gitflow.png-142.2kB

这个5个分支大体可以分为两类

  • 主要分支
master          //  主分支,永远保持稳定的状态,切下来就能跑
develop         //  最新的开发状态
  • 辅助分支 feature // 功能分支,基于develop,开发新功能时从develop新建分支开发,完成后合并回develop release // 准备发布的状态,用来预发、修复bugs,基于 develop, 完成后 merge 回 develop 和 master hotfix // 修复 master 上的问题, 等不及 release 版本就必须马上上线. 基于 master, 完成后 merge 回 master 和 develop 使用的话建议使用Source Tree,上面有git flow流程GUI,比较方便。

使用Sourece Tree的Git Flow时有一个小问题, 一般来说这套流程, 服 务器上只需要 master和develop两个分支的,但是有的公司要进行Code Review或者测试权限较大,release分支开发人员没有权限,我们公司就是这样。

定的流程是合并到release时需要发merge request,等待测试确认--为了保证release是经过自己或者测试大概测了一下没多大问题能进入预发的(或是需要等到组长进行code review也是一个道理)。

这时怎么办呢?

我的做法是按照要求在服务器建立master、develop、release三个分支,但是在将release分支check out到本地时,换一个名字比如叫remoteRelease,将Git Flow流程中的那个release辅助分支改成叫localRelease(进行Git Flow配置时是可以自己设置名字的)。当完成了release版本的开发,也进行了基本的测试后merge到本地的RemoteRelease中,再发起request,预发测试OK后点击finish release自动合并到master和develop中。

以上基本就是认真使用Git两个月和Git Flow两个月的总结,如果有遗漏欢迎指出。