Smiling & Weeping

                ---- 蝴蝶在双翼里藏匿夏的脉络

                    妄图在绿意中品鉴隆冬

第三章 Git分支管理

3.1 分支的简介

Git最重要的运用场景是多人协同开发,但是如何能保证每个人之间的开发不影响其他人的开发进程,Git 分支的出现就是解决了这个问题,使得每个人之间的开发是独立的,互不影响的。

有的人将 Git 的分支模型称为它的“必杀技特性”,也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。 为何 Git 的分支模型如此出众呢? 因为Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。 与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。 理解和精通这一特性,你便会意识到 Git 是如此的强大而又独特,并且从此真正改变你的开发方式。

3.2 分支的相关操作

3.2.1 分支的创建

Git分支的创建十分简单,我们可以使用git branch来查看现有的分支或创建新的分支。当不带任何命令参数时,输入git branch可以帮助我们查看当前项目所拥有的全部分支。并且Git会使用*来标明我们当前所处的分支上。

git branch
 
* master
 

当我们想要新增加新的分支时,只需要在git branch命令后面加上我们想要新建的分支的名称即可。

# 创建issue102的分支
git branch issue102
# 查看现有的所有分支
git branch
 
# 现有的分支
issue102
*master
 

我们可以发现虽然创建了issue102的分支,但是当前分支还是在master上。我们可以通过git checkout命令来进行切换分支。

3.2.2 分支的切换

在上面的例子中我们发现虽然创建了新的分支,但是当前分支还是在master分支上,我们需要通过git checkout命令切换到新建的issue102分支上,来进行后续的开发操作。

git checkout issue102
 
Switched to branch 'issue102'
 

这是我们可以在查看下当前分支的状态,我们可以发现当前分支已经转换到了issue102分支上。

git branch
* issue102
master
 

切换分支后,我们就可以进行自己的开发。分支上的文件状态是不同的。我们可以通过下面的例子有着更深入的了解。

# 切换分支
git checkout issue102 # 在分支上创建下新的文件
touch issue102.md
git add issue102.md
git commit -m "update issue102.md" touch issue102.html
git add issue102.html
git commit -m "update issue102.html"
 

在完成上述命令后,我们可以通过git log --oneline检查下当前Git的记录。

cd836b0 (HEAD -> issue102) update issue102.html
7575f02 update issue102.md
242c407 (master) update hello.md
 

我们可以发现issue102分支上的记录与master的记录间隔开了。除此之外,当我们切换回主分支后,我们还会发现master分支下没有新建的issue102.md和issue102.html两个文件。正如下图所示: 

3.2.3 分支的合并

当我们在分支上完成来开发工作后,我们需要将我们在当前分支进行的工作合并到主分支上。首先我们需要切回需要合并到的分支上,此处以issue102合并到master上为例子进行演示。

# 切换回主分支
git checkout master
# 使用git merge 进行合并
git merge issue102
# git branch --no-merged
# 查看所有未合并工作的分支
 

 我们可以发现原来在issue102分支上的文件已经合并到了主分支上了,并且issue102分支还存在。大家可以根据实际的需求进行分支的保留与删除。

有时候分支的合并不会一番顺利,当我们在两个分支中对同一个文件的同一个部分进行了不同的修改,Git就没有办法顺利的合并他们,会在合并的时候产生合并冲突。比如我们在issue102分支和master分支下对issue102.md文件进行了修改,当我们将issue102分支融合到主分支上时就会发生冲突。如下图所示: 

我们也可以通过git status查看命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件。当出现矛盾后,合并的文件内容将会出现"<<<<<<","=======",">>>>>>"等分割线来进行标记。如下图所示:

当出现了矛盾时,我们需要进行手动解决或者放弃合并。

  • 手动合并

    手动合并的方法很简单,就是我们选择我们要保留的代码,然后再把>>>>>, ======, <<<<<<这些提示行给去掉。最后重新进行add commit的操作即可。

  • 放弃合并

    当我们发现冲突所导致的改动量很大时,我们可以选择放弃该次的合并。我们可以使用git merge --abort放弃此次的融合。如果我们在运行了git merge之后又进行了一些人为的改动,那么在abort之后,所进行的改动也会被回滚掉。

  • mergetool

    除了手动合并以及放弃合并之外,我们还有一些其他的合并工具。git官方开发了一个专门用来合并的工具,叫做git mergetool(下图所示),它会将找到一份两个分支的祖先代码作为base(基准),然后再将两个分支的改动都列举出来作为对比,让我们在git编辑器当中决定要留下什么。在此处,我们不做过多的阐述,感兴趣的同学可以点击下方链接进行查看。

    1. Use vimdiff as git mergetool
    2. 使用vimdiff作为git mergetool
    3. git-mergetool

3.2.4 分支推送到远程

在很多情况下,我们都需要将分支推送到远程,在这一部分,我们将讲一些远程的相关操作。 首先,我们可以使用git remote -v查看远程库的详细信息。会显示我们可以抓取或推送的origin地址。

$ git remote -v
origin git@github.com:ProjectOwner/ProjectName.git (fetch)
origin git@github.com:ProjectOwner/ProjectName.git (push)
 

当我们需要推送本地分支到远程时,需要指定具体的本地分支。

# 推送本地的master分支到远程
git push origin master
# 推送本地的issue102分支到远程
git push origin issue102
 

但是当我们多人协作进行开发的时候,可能会出现远程分支比我们本地更新的情况,这时,我们就需要使用git pull的命令来试图合并。如果合并出现冲突时,我们需要解决冲突再提交。在这部分,推荐大家可以看下廖雪峰老师的Git教程中的 多人协作,如有侵权,请联系告知。

3.2.5 分支的删除

在Git中没有什么分支是不可以删除的(除了当前所在的分支不能删除),包括master分支也是可以进行删除。 Git的分支删除可以分为删除本地分支和远程分支。

  • 删除本地分支
# branchName 是需要删除的本地分支名字
git branch -d branchName
 

当我们想强行删除分支时,只需要将参数d改为D即可。

  • 删除远程分支
# origin 是远程的主机名
# branch 需要删除的远程分支
git push origin --delete branch
 

3.2.6 分支的重命名

当我们需要重命名分支的名称时,我们可以使用git branch命令来进行,具体方式如下:

# oldBranchName: 旧分支名
# newBranchName :新分支名
git branch -m oldBranchName newBranchName
 

当我们想要将改名后的分支推送到远程时,我们需要进行如下操作:

git branch -m oldBranchName newBranchName   # 将本地的分支进行重命名
git push origin newBranchName # 将新的分支推送到远程
git push --delete origin oldBranchName # 删除远程的旧的分支
 

3.3 分支开发工作流

当我们已经了解了分支的操作后,我们应该考虑使用一种怎样的方式使我们最大化的使用分支操作的优点。在接下来的这部分中,我们将会介绍一些常见的分支开发工作流程。而正是由于分支管理的便捷,才衍生出这些典型的工作模式,我们以后可以根据项目实际情况进行使用。

3.3.1 长期分支

在整个项目开发周期的不同阶段,我们可以同时拥有多个分支;然后我们可以定期地把某些主题分支合并入其他分支中。许多使用 Git 的开发者都喜欢使用这种方式来工作,比如只在 master 分支上保留完全稳定的代码——有可能仅仅是已经发布或即将发布的代码。 他们还有一些名为 develop 或者 next 的平行分支,被用来做后续开发或者测试稳定性——这些分支不必保持绝对稳定,但是一旦达到稳定状态,它们就可以被合并入 master 分支了。这样,在确保这些已完成的主题分支(短期分支,比如之前的 issue102 分支)能够通过所有测试,并且不会引入更多 bug 之后,就可以合并入主干分支中,等待下一次的发布。 

3.3.2 短期分支

短期分支也可以叫做主题分支,它的作用是用来实现某一种特性或者相关工作(修复bug,开发产品新特性)。比如当我们的产品出现了bug时,我们应该新建一个分支并起名为bug分支,并在该分支上进行bug的修复,等我们的代码确定不会引起其他bug时,我们就可以合并到主分支上进行修复。当我们看见issue时,我们也可以使用同样的方式来解决issue的问题。常见的短期分支还有上面提到的develop,topic分支。在实际开发中,我们应该按照以下几个基本原则进行分支开发工作流程

  1. master分支应该是最稳定的,也就是仅用来发布新版本,平时不能直接在上面进行操作,应该保存在远程。
  2. 短期分支是我们干活的分支,短期分支可以不用上传到远程,当我们完成了bug的修复,新功能的开发时才需要合并到主分支上。
  3. 多使用分支来进行开发工作。

文章此结束,我们下次再见

-- 心间荒芜却似长夜,有盘逢朝霞

Lecture3的更多相关文章

  1. Linear Algebra lecture3 note

    Matrix multiplication(4 ways!) Inverse of A Gauss-Jordan / find inverse of A   Matrix multiplication ...

  2. cs231n spring 2017 lecture3 Loss Functions and Optimization 听课笔记

    1. Loss function是用来量化评估当前预测的好坏,loss function越小表明预测越好. 几种典型的loss function: 1)Multiclass SVM loss:一般的S ...

  3. CS20SI-tensorflow for research笔记: Lecture3

    本文整理自知乎专栏深度炼丹,转载请征求原作者同意. 本文的全部代码都在原作者GitHub仓库github CS20SI是Stanford大学开设的基于Tensorflow的深度学习研究课程. Tens ...

  4. Lecture3.随机变量及其概率分布

    1.随机变量的定义 2.随机变量的类型: 若随机变量X的可能取值是有限个或可列个, 则称X为离散型随机变量. 反之,则称X为非离散型随机变量. 若随机变量X的可能取值“连续”(“不间断”),则称X 为 ...

  5. CS61A Lecture3 Note

    本次lec主讲控制流 本文档只列一些py控制流与C不同的地方  print的功能不同 可以print出来None这种东西 重点讲了函数运行机制,我的理解是这样的,在调用函数之前,def会产生一个glo ...

  6. David Silver强化学习Lecture3:动态规划

    课件:Lecture 3: Planning by Dynamic Programming 视频:David Silver强化学习第3课 - 动态规划(中文字幕) 动态规划 动态(Dynamic): ...

  7. cs231n spring 2017 lecture3 Loss Functions and Optimization

    1. Loss function是用来量化评估当前预测的好坏,loss function越小表明预测越好. 几种典型的loss function: 1)Multiclass SVM loss:一般的S ...

  8. GO語言視頻教程

    第1课:https://github.com/Unknwon/go-fundamental-programming/blob/master/lectures/lecture1.md Go开发环境搭建h ...

  9. 蒙特卡洛法计算定积分—Importance Sampling

    如上图所示,计算区间[a  b]上f(x)的积分即求曲线与X轴围成红色区域的面积.下面使用蒙特卡洛法计算区间[2  3]上的定积分:∫(x2+4*x*sin(x))dx # -*- coding: u ...

  10. SLAM(二)----学习资料下载

    有位师兄收集了很多slam的学习资料, 做的很赞, 放到了github上, 地址:https://github.com/liulinbo/slam.git ruben update 0823 2016 ...

随机推荐

  1. [DApp] Moralis 无服务架构方式构建 DApp

    Moralis 提供的使用功能包括三个方面: 进一步封装Web3功能的 Moralis SDK,极大方便了开发者对于DApp基础功能的开发,比如 MetaMask登录验证,签名,IPFS集成,DApp ...

  2. [FAQ] ErrorException of l5-swagger:generate, Required @OA\Info() not found

    l5-swagger 除了要添加 @OA\Get() 针对方法的注释之外,每个 Controller 还需要一个概述信息,如下: /** * @OA\Info( * title="Auth ...

  3. [FAQ] uni-app 运行微信小程序 main.wxss 报错 unexpected token "$"

    检查一下你是否在 App.vue 中有手动操作引入过 uni.scss,比如下面的 import: <style lang="scss"> @import url(&q ...

  4. Maven的概述

    Maven的概述 @ 目录 Maven的概述 2. 依赖 3. Maven 的工作机制 3. 最后:感谢 Java 项目开发过程中,构建指的是使用『原材料生产产品』的过程. 原材料 Java 源代码 ...

  5. Python 潮流周刊#49:谷歌裁员 Python 团队,微软开源 MS-DOS 4.0

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  6. .NET静态代码织入——肉夹馍(Rougamo)发布3.0

    肉夹馍(https://github.com/inversionhourglass/Rougamo)通过静态代码织入方式实现AOP的组件,其主要特点是在编译时完成AOP代码织入,相比动态代理可以减少应 ...

  7. nim 8. 异常处理

    基本的异常处理 try: let d = newSeq[int]() echo "value: ", d[2] except: let e = getCurrentExceptio ...

  8. 动态修改manifest.json

    点击查看代码 // h5开发环境 const h5Dev = { baseUrl: 'https://devh5.....' } // h5测试环境 const h5Test= { baseUrl: ...

  9. .NET 代理模式(二) 动态代理-DispatchProxy

    前言 我们都知道,在.NET中实现动态代理AOP有多种方案,也有很多框架支持,但大多框架的实现原理都是通过Emit配合Activator一起使用,从IL级别上实现动态代理. 其实在.NET中有一个更为 ...

  10. AIRIOT训练营沈阳站圆满结束|手把手教你搞定物联网应用开发

    8月28日-9月1日,由航天科技控股集团有限公司(以下简称"航天科技")主办的<AIRIOT物联网平台应用与实战>训练营在沈阳圆满结束,来自上海电机学院.中渝软通信息技 ...