Git专栏6:git的分支详解以及实际项目里的操作

前言

几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本,对大型项目来说会花费很长时间。

有人把 Git的分支模型称为“必杀技特性”,而正是因为它,将 Git 从版本控制系统家族里区分出来。Git 有何特别之处呢?Git 的分支可谓是难以置信的轻量级,它的新建操作几乎可以在瞬间完成,并且在不同分支间切换起来也差不多一样快。和许多其他版本控制系统不同,Git 鼓励在工作流程中频繁使用分支与合并,哪怕一天之内进行许多次都没有关系。理解分支的概念并熟练运用后,你才会意识到为什么 Git 是一个如此强大而独特的工具,并从此真正改变你的开发方式。

一.概括

1、Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。
2、Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。
3、Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。
4、Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。
5、Git 的内容完整性要优于 SVN:Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。

image.png
SVN的分支介绍

我们首先要创建一个分支,然后checkout分支。checkout完成后我们会发现分支branch在我们本地,其实就是对trunk(主干)的一个完全拷贝。
我们本地会多出一个branch的文件夹,目录结构跟trunk(主干)一模一样。
那么怎么样来进行并行开发呢?试想一下,分支在开发的同时,trunk(主干)也在开发,最后trunk(主干)开发完成需要合并到主分支时,可能会存在一堆的冲突。这个怎么避免呢?是这样,在并行开发的同时,我们也要时常更新本地trunk(主干)并且把trunk合并到branch上,保持分支与仓库的实时更新,这样才不会产生大量冲突。等功能开发和测试完成,就可以把branch内容合并到trunk(主干)中,然后删除branch,提交trunk(主干)。这样才是一个完整的svn分支开发流程。我们注意到,本地的branch其实是对trunk的一个完全拷贝。会发现,使用SVN的分支开发还是挺麻烦的。

git分支的分支介绍

git分支与SVN分支显然大不一样。git创建一个本地分支只需要在初始化一个本地git仓库后执行 git branch ,就可以创建一个名字为branchName的本地分支。使用checkout命令可以切换分支,这个在上篇已经介绍过了。我们会发现,创建分支过后,本地仓库并没有多出分支文件夹,也就是说git创建分支并没有对主分支进行完全拷贝,这个跟svn是大便不相同的。在git分支上进行的操作,提交过后,可以合并到主分支上,合并完成后,创建的git分支即可删除。

在这里多说一下,使用git作为版本控制,每开发一个新功能或者修复一个bug都应该新建一个分支来进行操作。不然几个模块并行开发的时候,你都在主分支上操作,到时候有一个功能好了,需要提交测试,你应该怎么提交?需要人工识别哪些文件能提交,哪些文件不能提交。这显然不是一种好的做法。好的做法是每个功能模块使用分支进行开发,功能好了过后在分支提交然后往主分支master上合并,这样不用纠结那些文件能有提交推送哪些不能。

理解下 Git 工作区、暂存区和版本库概念:
工作区:图中左侧的,就是你在电脑里能看到的目录。
暂存区:图中右侧的,版本库下面的,英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。

image.png

git一般会存在一些这样的分支:

image.png

master(线上),develop(开发),release(预发布),hotfix(线上bug修复)这四种常用的分支

  • master: 主分支;主要是稳定的版本分支,正式发布的版本都从Master拉。
  • develop: 开发分支;更新和变动最频繁的分支,正常情况下开发都是在Develop分支上进行的。
  • release:预发行分支;一般来说,代表一个版本的功能全部开发完成后递交测试,测试出Bug后进行修复的分支。
  • features: 功能分支; 其实Features不是一个分支,而是一个分支文件夹。里面包含了每个程序员开发的功能点。Feature开发完成后合入Develop分支。
  • hotfix: 紧急故障修复分支(如现场故障),内部分支,从master拉出此分支,merge到master和develop分支。最希望不会被创建的分支;这个分支的存在是在已经正式上线的版本中,发现了重大Bug进行修复的分支。

git分支就是在版本控制过程中,使用多条线同时推进多个任务。
每个新功能位于一个自己的分支,这样可以push到中央仓库以备份和协作。但功能分支不是从master分支上拉出来的新分支,而是使用develop分支作为分支。当新功能完成时,合并回develop分支。新功能的提交不直接与master交互。

一旦develop分支上的功能到了发布日期,就从develop分支分一个发布分支(一般叫release)。
release分支用于预发布测试,所以从这个时间点开始后新的功能不再加到这个分支上,release分支只应该做bug修复、文档生成和其他面向发布的任务。一旦release测试完毕并准备发布后,将其合并到master分支并分配一个版本号打上Tag。另外,release上做的bug修改要合并回develop分支。
使用一个专门用于发布的分支,是一个团队可以在完善发布版本的同时,另一个团队继续开发下一个版本功能。

一个项目里,主分支master分为几部分分支feature,处理不同的部分,如,一个游戏项目,可以分出搞图像的、搞运算的、操作的等分支。在公司里,每个团队处理属于自己的分支,不同部门分支互不干扰,也不影响主分支,假如某个分支出现严重错误,只需要删除这个分支重新来过,其他分支没影响。当一个分支开发完成,就把他合并到主干中,全部分支开发完后,最终形成整个项目。

然而,主干master也可能出现bug,这个时候就有一个host_fix分支(临时分支,用来修复bug,修复完及时合并为主干)

二. 分支的好处

  • 同时并行推进多个功能开发,提高开发效率
  • 各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开发即可

三. 分支操作-(这里主要以gitlab为例进行说明)

这里讲的是终端操作,很多第三方软件有自己的快捷键,不做介绍。
下面是从dev拉取分支,拉取的时候选择的是dev,然后代码拉到本地。

  • step1:创建分支
  • step2:查看分支 并且切换到该分支
  • step3:拉取需要合并的分支代码比如dev分支
  • step4:在当前分支下 合并dev
  • step5:提交合并的代码,到自己的远程分支
  • step6:推送 提交到服务器
  • step7:然后去第三方平台gitlab上,去将自己分支代码合并dev,告诉审核人去审核和合并。

step1:创建分支 或者在第三方软件上面操作

git branch 分支名

step2:查看分支 切换到该分支 或者在第三方软件上面操作

git branch -v // git branch 这两个命令一样 查看分支,有个*标记的为当前分支
// git branch -a  列出所有分支

git checkout 分支名 //切换到该分支

注释:这时候,已经是当前分支了,去写代码了。。。开发完成,就再进行下面的操作。

step3:拉取需要合并的分支代码比如dev分支 或者在第三方软件上面操作

git checkout dev
git pull

step4:在当前分支下 合并dev

git checkout  分支名
git merge dev 

这时候有冲突或者问题,需要修改冲突和问题

step5:提交合并的代码,到自己的远程分支

git add .  #添加所有改动文件到缓存
git commit  -m "注释描述"  #提交
git status     #查看修改文件后的状态 

step6:推送 提交到服务器

git push

step7:然后去第三方平台gitlab上,去将自己分支代码合并dev,告诉审核人去审核和合并。

下面有个step7操作的例子
①在界面中点击New merge request新建一个 Merge Request

image.png

②左侧选择需要合并的show-overflow-tooltip分支为当前分支(Source branch),在右侧选择合并到的目标分支(Target branch)设置为dev,确认无误,点击Compare branches and continue提交

image.png

在界面中,单击提交合并按钮来Submit merge request进行合并。在gitlab中提交合并请求,Assignee 选中项目管理员。然后你就可以看到状态被修改为合并了,你在分支中所有的修改将会合并到你希望合并到的分支中去了。

image.png

③最后,可以看到这个分支合并merge,可以直接粘贴在浏览器里面的地址,发给合并的负责人(假如他没看到),告诉他需要合并。

image.png

经过以上五个步骤之后我们在gitlab上就可以看到我们所做的改动了~

四:我们在项目里面的具体操作实例:

一:假如我们现在在自己本地的分支mapOrder上开发,刚开发完项目,执行了下列命令,将本地分支mapOrder代码,推到远端分支mapOrder上:

git  add .
git  commit -m '提交的备注信息'
git status     #查看修改文件后的状态 
git  push 

二:现将主线v1.0.0分支合并到自己的分支本地mapOrder,解决完问题,再去提交和推送到远端mapOrder,然后再去gitLab上创建合并请求,相关负责人去合并。

我们一开始一般是在自己的分支环境下,所以需要先拉取远端的代码,合并代码,解决冲突等问题

## 1,查看分支列表  *标记的就是当前分支
$ git branch -a

## 2,切换到v1.0.0分支 
$ git checkout v1.0.0  

## 3,拉取v1.0.0 分支 代码
$ git pull

## 4,切换到本地 mapOrder 分支
$ git checkout mapOrder

## 5,合并本地 v1.0.0 到 本地 mapOrder  #或者在sourcetree上操作如下面的图
git-merge命令是用于从指定的分支(v1.0.0)  合并到 当前分支(mapOrder)的操作

$ git merge v1.0.0 

注意:
1,组件化的项目,需要删除pod.lock,然后 pod install。
2,此时,可能会有冲突和问题,解决完成,再进行去下操作。

$ git  add .   #加到缓存区  
$ git  commit -m '提交的备注信息'   #提交到本地仓库
$ git status     #查看修改文件后的状态 

## 6,在本地分支mapOrder的环境下,将 本地合并代码 推到远程mapOrder
$ git push

## 7,最后,去gitLab上创建合并请求。就是把远端 mapOrder分支 合到远端 v1.0.0 分支上去。
要注意:主要 source【mapOrder】和 taget【v1.0.0】,以及指定相关负责人,相关负责人去合并。
这一步可以看上面的 【 三. 分支操作-(这里主要以gitlab为例进行说明)】里面的【step7】 操作的例子。

上面第5步也可以在sourcetree上操作,sourcetree上的操作如下图(##5,合并本地 v1.0.0 到 本地 mapOrder):需要在mapOrder分支环境下,右击v1.0.0 合并到 mapOrder

image.png

五 :git更改远程仓库指向 remote url

在我们的远程仓库地址变更后(比如:开发了一段时间,然后Git第三方的代码托管平台需要把项目换到另一个平台或新地址(比如从gitlab一个项目地址换到gitlab上另外一个,或者从GitHub换到gitee),那么我们写好的代码怎么办呢?怎么和新的代码仓库联系起来,拉取和推送等管理呢?)

解决:更改远程仓库指向,就行了

git remote set-url origin  项目新的URL
//举例子 git remote set-url origin [email protected]:test/thinkphp.git

此法源于此文:git更改远程仓库指向 git remote set-url origin url

你可能感兴趣的:(Git专栏6:git的分支详解以及实际项目里的操作)