前两篇博客集中的聊了git的一些常用命令,具体请参见《Git知识总览(一) 从 git clone 和 git status 谈起》、《Git知识总览(二) git常用命令概览》。本篇博客主要涉及了在git版本管理中的分支的创建、切换以及合并。并且罗列了在merge分支使发生冲突时的解决方式。同时还介绍了如何删除本地分支以及远程分支。本篇博客除了参考ProGit中的内容,还参考了learngitbranching这个网站进行的git分支内容的学习和梳理。下方的示例有的给出了基于LearningBranching的示例,有的是基于真实分支操作的示例。本篇博客只是git分支管理的部分知识,下篇博客会继续总结git分支的相关操作。

一、分支创建与切换

1、创建新的分支并切换到该分支上进行提交

首先我们先从最简单的来,下方演示了git分支的创建和切换的最基本的操作,具体步骤如下:

  1. git branch <分支名> : 首先使用 git branch bugfix01,在当前分支也就是master分支上创建了一个名为bugfix01的新分支。

  2. git checkout <分支名> : 然后使用 git checkout bugfix01 命令来切换到我们新创建的bugfix01的新分支上。

  3. git commit : 最后使用 git commit 命令在新的分支上进行代码提交。

  

从上面的操作上我们不难看出,其中的星号*表示git的 HEAD 指针,指向当前所在分支。开始时 HEAD指针指向的是master分支,也就是用户当前所操作的分支是master。使用 git branch 创建一个新的分支后,HEAD的指向并没有改变,仍然指向的是master分支。当使用 git checkout 命令后,HEAD 指针就由 master 分支转向了 bugfix01 分支了,这样我们就可以对bugfix01进行操作了。

上面还需要注意的时,在创建好分支后,如果在新的分支上没有提交的话,那么 bugfix01 分支和 master 分支所指向的提交号是一致的,上面都是 C1。 这个 C1 表示的就是每次提交的哈希值,也就是提交号。当使用 git commit 时,说明在分支上有新的提交了,就会在之前的提交的基础上往下延伸一个提交,也就是 C2。后提交的 C2 会有一个指针指向上一个提交C1。

2、上述操作在终端的表现

接下来我们来看一下终端的具体操作。下方是最初的状态,目前所在的分支为master分支。从下方可以看出该分支上的Tag号,以及HEAD指针指向的master。

  

然后我们使用 git branch bugfix01 创建一个新的分支。从下方可以看出 bugfix01分支的指针指向的commit号和master的commit号一致,原因是我们从master中开出来的分支。不过当前所操作的分支仍然是master (HEAD -> master)。

  

因为我们从master分支上切换到了bugfix01分支上,所以此刻的HEAD指针指向的是bugfix01

  

然后我们在bugfix01上提了一些代码,此刻我们看到bugfix01指向最新的commit,但是HEAD一直是指向当前分支bugfix的。

  

上面这些操作所使用的命令如下所示:

  

3、创建并切换分支

我们可以使用一个简写的命令来创建并切换到该分支上,下方就演示了这一操作:

  1. git checkout -b <分支名> : 首先使用 git checkout -b bugfix02 命令在当前所在分支bugfix01上创建一个新的分支并且切换到新创建的bugfix02上。

  2. git commit : 然后就可以使用 git commit 在新的分支 bugfix02 上进行提交了。

  

上述命令在终端上的执行结果就不做过多赘述了,请参见第二部分。

4、切换到之前的分支并提交

下方的使用场景是切换到之前已经创建好的分支上,并在切换后的分支上进行提交。下方操作后就会形成分叉。

  1. git checkout <分支名> :目前所在分支是bugfix02, 然后使用 git checkout bugfix01 命令将分支切换到 bugfix01上。

  2. git commit : 切换后就可以在bugfix01上进行提交操作了。

  

上篇博客中也聊到了,在终端中,我们可以使用 git log --oneline --graph --all 来查看所有分支情况。具体如下所示:

  

二、分支的合并与删除以及冲突解决

上一部分是如何创建分支和在各个分支间进行切换,接下来我们就来看一下分支的合并与删除。

1、分支的合并-merge

我们还以上面那个示例来看一下分支的合并。下方的操作主要是分支的合并、当在两个分支 bugfix01 和 bugfix02 上修改了相关bug, 并且需要将修改后的代码合入到master分支上。下方就是这一系列的操作:

  • 首先使用 git checkout master 命令切换到master分支上。

  • 然后使用 git merge bugfix01 命令将 bugfix01 分支的修改合入到master分支上,在合入成功后会将合入后的新文件进行提交,此刻会有一个新的commit号,也就对应着下方的C9。

  • 然后使用 git merge bugfix02,在将 bugfix02上的修改合入到master分支上,merge 对应的commit号为C10。

  • 最后还是可以在master分支上进行正常提交的。

  

下方就是我们在真正的分支中进行的分支合并的操作,我们将 bugfix01 分支merge到了master分支上。从下方可以看到 bugfix02 还尚未合入Master分支。稍后我们会在处理冲突的示例中将bugfix02分支合入到master分支中。

  

2、分支的删除

上面可以看到,虽然 bugfix01 和 bugfix02 的分支已经被合入到master分支上了,但是这两个分支还是存在的。如果我们不需要这两个分支指针了,可以将两个分支指针进行删除:

  • 首先使用 git branch -d bugfix01 对分支 bugfix01 进行删除。

  • 然后使用 git branch -d bugfix02 对分支 bugfix02 进行删除。

从下方的操作上来看对分支的删除只是删除的指向该commit号的指针,并不会删除其相关的提交号, 在日志中仍然可以找到之前的commit记录,也仍然可以在该commit上创建新的分支。如果你想删除远端的分支的话,那么得使用 $ git push origin --delete <分支名> 了。

  

还是要依附于实例,下方对上一部分已经合入master分支的bugfix01分支执行了删除操作,删除成功后会提示 “Delete branch bugfix01 ( was 223aefb)”, 后边这个就是删除分支所对应的commit号的前7位。

  

从下方截图中可以看到,其中bugfix01这个分支被删除了,不过删除的只是指向该commit号的一个指针或者别名,其他的都没改变。

  

3、冲突解决

上面是不冲突时的正常流程,如果在分支合并时,两个分支同时修改了同一个文件的同一个地方。此刻分支合并时就会冲突,就需要人工介入来解决冲突的代码了。上面我们说留着 bugfix02 这个分支是有用的,现在就来看一下bugfix02 这个分支的用处。从下方的 log 中不难发现,bugfix02分支和 master 分支都修改该了README.md文件的第二行数据。接下来我们就将 bugfix02 合入 master分支上。

  

下方截图的内容就是我们将 bugfix02 分支合入到 master分支时所报的冲突。冲突的大概意思就是在合并 README.md 文件时产生了冲突,自动合并失败了,需要修复这个冲突,在修复之后再对结果进行提交。我们可以使用 git status来查看一下当前的状态(配置的别名 git st)。从 git status的提示中也可以看到,你可以修复该冲突,然后使用 git commit 进行提交,或者 使用 git merge --abort 命令放弃本次合并。如果放弃本次合并就会回到合并之前的状态,当然,这并不是我们想要的,下方会对冲突进行解决,并提交,

  

接下来我们就来看一下冲突的具体内容,从<<<<<<<<开始到>>>>>>>>>结尾是冲突的部分,两个分支的内容由========进行分割。上方是当前分支所修改的内容, 我们需要将冲突的内容进行合并,根据具体情况具体分析,看那些需要保留那些不需要保留。还是都需要保留。

  

下方就是我们修改冲突后的内容,修复策略是保留了master的修改,删除了bugfix02分支的修改。然后将修改的文件进行提交即可,在此就不做过多赘述了。

  

4、使用工具进行冲突解决

输入 git mergetool 然后根据提示输入opendiff, 在Mac下会打开Xcode自带的FileMerge工具。

  

下方就是启动的 FileMerge 工具, 在使用该工具进行文件merge时,可以选择几种文件合并策略。比如以左边为准,以右边为准等。

  

上述工具位于Xcode的开发工具中,如下所示:

  

三、分支的查看以及强制删除

首先我们使用 git log --oneline --graph --all 命令来可视化的看一下目前的分支状态。从下方的截图中我们可以看到,目前共有三个分支 master、bugfix02、bugfix03。并且我们可以看出bugfix02已经合入master分支,bugfix03尚未合入。

  

下方是一系列查看分支的一些方法:

  • git branch : 查看所有分支,其中前面有星号的是当前所在分支,下方即为master分支。

  • git branch -v : 查看所有分支和该分支上最后的一次提交。

  • git branch --merged : 查看已经合入当前分支的所有分支。

  • git branch --no-merged : 查看未被合入分支。

  

今天博客关于git分支管理的内容就先到这吧,下篇博客会详细介绍 rebase 以及 cherry-pick 等相关内容。

Git知识总览(三) 分支的创建、删除、切换、合并以及冲突解决的更多相关文章

  1. Git知识总览(四) git分支管理之rebase 以及 cherry-pick相关操作

    上篇博客聊了<Git知识总览(三) 分支的创建.删除.切换.合并以及冲突解决>,本篇博客我们主要来看一下 rebase 变基相关的操作.rebase 操作和 merge 操作最终都可以达到 ...

  2. Git知识总览(二) git常用命令概览

    上篇博客我们从 git clone 和 git status 两个命令开始,引出了一系列的git操作命令, 请参见:<Git知识总览(一) 从 git clone 和 git status 谈起 ...

  3. git拉取远程分支并创建本地分支和Git中从远程的分支获取最新的版本到本地

    git拉取远程分支并创建本地分支 一.查看远程分支 使用如下Git命令查看所有远程分支: git branch -r 二.拉取远程分支并创建本地分支 方法一 使用如下命令: git checkout ...

  4. Git知识总览(六) Git分支中的远程操作实践

    前几篇博客陆陆续续的讲了好多关于Git操作的内容,本篇博客仍然也不例外,不过本篇博客的主题是关于git的远程操作的.依照之前博客的风格,我们依然依托于LearningGitBranch中的相关内容来探 ...

  5. Git知识总览(一) 从 git clone 和 git status 谈起

    本篇博客是整理git相关知识的第一篇,因为之前一直是用SourceTree对Git的命令行操作用的不是特别熟,于是乎过了一遍ProGit(链接:https://git-scm.com/book/zh/ ...

  6. Git知识总览(五) Git中的merge、rebase、cherry-pick以及交互式rebase

    上篇博客聊了<git分支管理之rebase 以及 cherry-pick相关操作>本篇博客我们就以Learning Git中的关卡进行展开.下方列举了LearningGit中的 merge ...

  7. git 使用笔记(三)-分支的使用

    简单介绍 之前说过,每次修改之后,Git 并不是保存这些修改之后的差异变化,实际上就像一个照相机一样,将修改后的文件拍下作为文件快照,记录在一个微型的文件系统中.在 Git 中提交时,会保存一个提交对 ...

  8. git拉取远程分支并创建本地分支

    本地分支推送至远程 git checkout local_branch git push origin local_branch:remote_branch 一.查看远程分支 使用如下Git命令查看所 ...

  9. git 分支的创建和切换

    每次提交,GIT 都会将他们串成一个时间线,截止到目前,只有一个时间线,GIT里叫这个分支为主分支,叫master,HEAD指向master,master指向提交,HEAD指向当前的分支. 一开始的时 ...

随机推荐

  1. SparkStreaming读取Kakfa数据时发生OffsetOutOfRangeException异常

    参考文章:http://www.jianshu.com/p/791137760c14 运行SparkStreming程序一段时间后,发现产生了异常: ERROR JobScheduler: Error ...

  2. Android开发——Toast知识

    Toast.makeText(this, "内容", Toast.LENGTH_SHORT).show(); 直接显示一个Toast,第三个参数是时间的长短,还有一个Toast.L ...

  3. 引号在jsp页面中正确显示的处理

    写在前面: 在前面的博客中已经有了对一些特殊字符的处理,但是万万没有想到,出来了一个含有引号的字符串,比如这样的ab"c"d的一个字符串.如果在超链接传值的时候,会与前面的引号成对 ...

  4. 【CSS3】内联、内部、外部样式,样式优先级、层叠、继承

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. Oracle11g不能导出空表问题

    ORACLE 11g 用exp命令导出库文件备份时,发现只能导出来一部分表而且不提示错误,之前找不到解决方案只能把没导出来的表重新建建立.后来发现是所有的空表都没有导出来.于是想好好查查,因为在以前的 ...

  6. 常用的 JS 排序算法整理

    关于排序算法的问题可以在网上搜到一大堆,但是纯 JS 版比较零散,之前面试的时候特意整理了一遍,附带排序效率比较. //1.冒泡排序 var bubbleSort = function(arr) { ...

  7. [置顶] webapi token、参数签名是如何生成的

    一个问题 在这里我想问大家一句,如果你向一个刚刚接触.net web后端程序开发的同学(别人刚刚也就学了webform的request,response,会提交表单的这种刚接触不久的同学),你怎么去解 ...

  8. 如何在yarn上运行Hello World(二)

      在之前的一篇文章我们介绍了如何编写在yarn集群提交运行应用的AM的yarnClient端,现在我们来继续介绍如何编写在yarn集群控制应用app运行的核心模块 ApplicationMaster ...

  9. Docker(四):Docker基本网络配置

    1.Libnetwork Libnetwork提出了新的容器网络模型简称为CNM,定义了标准的API用于为容器配置网络. CNM三个重要概念: 沙盒:一个隔离的网络运行环境,保存了容器网络栈的配置,包 ...

  10. lesson - 11 正则表达式

    正则就是有一定规律的字符串,有几个特殊符号很关键(. * + ? | ),我们平时不仅可以用命令行工具grep/sed/awk去引用正则,而且还可以把正则嵌入在nginx.apache.甚至php.p ...