前言
几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本,对大型项目来说会花费很长时间。
有人把 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 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
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 的版本库。
git
一般会存在一些这样的分支:
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
②左侧选择需要合并的show-overflow-tooltip
分支为当前分支(Source branch
),在右侧选择合并到的目标分支(Target branch
)设置为dev
,确认无误,点击Compare branches and continue
提交
在界面中,单击提交合并按钮来Submit merge request
进行合并。在gitlab
中提交合并请求,Assignee
选中项目管理员。然后你就可以看到状态被修改为合并了,你在分支中所有的修改将会合并到你希望合并到的分支中去了。
③最后,可以看到这个分支合并merge
,可以直接粘贴在浏览器里面的地址,发给合并的负责人(假如他没看到),告诉他需要合并。
经过以上五个步骤之后我们在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
。
五 :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