什么是分支

在玩剧情类游戏时,不同的选择会触发不同的剧情路线,每条剧情路线都会独立发展,最终走向不同的结局。

Git中所谓的“分支(branch)”就如同游戏中的剧情路线,用户可以为项目建立不同的分支,使得项目能在不同的分支里独立进行,并且互不干预。

当用户初始化一个仓库时,Git会自动为其建立一条主分支,默认称其为master。若用户没有创建其他分支,那么项目发展的各个版本就默认存储在这条 master 分支上。

分支指令介绍

分支的新建和切换

假设你正在项目上工作,并且在 master 分支上已经有了如下的提交。

对应的图即为如下:

master 指针指向该分支上最新的提交; HEAD 指针指向的是当前所在分支。

此时你发现了项目中有一个代号为#11的bug需要你解决。你决定专门新建一个分支,在那条分支上把该问题解决。于是你敲入了新建分支的指令。

上面两行命令可以仅用一条命令替代:$ git branch -b bug#11

当我们在创建新的分支时,实际上是创建一个新的指针。它会指向 master 此时指向的提交。当我们切换到分支 bug#11时,HEAD 指针就会指向 bug#11,如下图所示。

此外,我们可以用如下命令查看了目前仓库中存在的分支。

可以看到目前共存在2个分支,其中带*号的是目前所在分支:master

分支的作用

于是你开始在 bug#11 这条分支上工作,并作出了如下的提交(commit)。

于是 bug#11 指针往前移动了一步,而 master 指针还是留在原地。

这时,当你用 $ git checkout master 命令切换回 master 分支时,你发现刚才在 bug#11 分支上新建的 log.txt 文件不见了,当前的工作目录和你开始在 bug#11 分支工作前一模一样。

这就是分支的好处,它将工作切分开来,让工作多线独立发展。

合并分支

我们将介绍在合并分支时会遇到的3种情况。

Fast-Forward

此时,你已经把 #bug11 修复完毕,你决定把这项修复合并到主线 master 中。于是,你使用了 $ git merge 命令来实现这个目的。

在合并的时候,你注意到了“快进(Fast-forward)”这个词。当你试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进,因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”,如图所示。

此时合并完成,所以你也不再需要 bug#11 分支了。你可以使用带 -d 选项的 $ git branch 命令来删除分支:

'recursive' strategy

此时,你又发现了项目中有一个代号为 bug#31 的漏洞需要修复,于是你先用 $ git branch bug#31 命令新建了一个分支。

现在的你还在 master 这条分支上工作:你将 Scheduling.txt 的文件内容修改为 Project Scheduling - 85% Done., 然后commit这次的修改。

此时,对应的图为如下:

现在的你感到心满意足,决心切换到 bug#31 分支上开始修复 bug#31。于是你先用 $ git checkout bug#31 命令切换到了该分支。

接着你辛辛苦苦了一整天,总算把 bug#31 修复完了。于是你修改了 log.txt 文件里的内容,加上了一行Fixed bug#31. ,并commit这次的修改,此时的图对应如下:

现在,你决定把对 bug#31 的修复应用到 master 分支中来,于是你切换回 master 分支,然后再次调用了 $ git merge 命令:

你发现这次提示的和之前在合并 bug#11 分支时提示的不太一样。因为此时,你想合并的 bug#31 指向的最新提交 C4 并不是 master 指向的最新提交 C3 的直接后继(换句话说,C3 不能顺着一条路走到 C4)。所以Git没法再那么通过简单的移动指针来完成合并了。

Git会找到 C3C4 的共同祖先 C2,然后做一个三方合并。

那么什么是三方合并呢?

例子1:A是B和C的共同祖先。B相对A的改动是删掉了3,C相对A的改动是增加了1。那么B和C合并的结果就是123。

例子2:A是B和C的共同祖先。B相对A的改动是删掉了1,C相对A的改动是增加了3。那么B和C合并的结果就是23。

所以简单来说,三方合并就是把B方和C方相对于共同祖先A方的改动分别应用到合并结果上。

刚才,C3 相对于 C2 的改动是修改了 Scheduling.txt 文件的内容,而 C4 相对于 C2 的改动是修改了 log.txt 文件里的内容,将这两项改动都应用到合并结果中,就得到了一个既修改了 Scheduling.txt 又修改了 log.txtC5

遇到冲突时的合并

有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个文件进行了不同的修改,Git 就没法干净的合并它们。

例如:你在 bug#31 分支中在 README.md 文件中添加了一行 I like Git.;在 master 分支中对 README.md 文件添加了一行 Git is good.,然后再执行 $ git merge 命令:

在两个分支中,你都对 README.md 文件进行了修改,因此就会产生合并冲突。

打开 README.md 文件会看到如下内容,其中 <<<<<<< HEAD======= 之间的内容是 HEAD 指向分支里的内容,即 master=======>>>>>>> bug#31 之间的是 bug#31 分支里的内容。

你手动修改了这个文件,修改后的内容如下。

Git轻松入门1:本地仓库篇,我们提到过,文件修改后,需要执行 $ git add$ git commit 两个步骤。所以现在,你同样需要执行这两个步骤,而当你敲完命令,你会发现提示合并成功。

总结

总结一下今天出现过的几个Git命令:

# 列出该仓库存在的分支,当前分支的前面会带有*号
$ git branch # 创建分支
$ git branch [branch-name] # 切换分支
$ git checkout [branch-name] # 创建分支并立刻切换到该分支下
$ git checkout -b [branch-name] # 删除分支
$ git branch -d [branch-name] # 合并分支
$ git merge [branch-name]

分支的作用在于将工作切分开来,使得工作可以多线独立发展。以上是本讲关于分支命令的概括。此外,本讲还介绍了Git采取的3种合并策略:Fast-forward(直接移动指针),recursive strategy(采取三方合并)以及merge conflict(手动修改存在冲突的文件)。

参考

  1. http://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging
  2. https://www.zhihu.com/question/30200228
  3. https://www.liaoxuefeng.com/wiki/896043488029600/900003767775424
  4. https://www.runoob.com/git/git-branch.html

有问题欢迎大家在评论区留言,转载请注明出处。

Git轻松入门2:分支篇的更多相关文章

  1. Git轻松入门3:远程仓库篇

    在第一讲中,我们有介绍过:Git是分布式版本控制系统.每个人的电脑上都有一份完整的版本库.当对项目作出了修改后,只要把修改推送给对方即可.但很有可能的情况是:两台电脑不在一个局域网内,无法互相访问:或 ...

  2. Git轻松入门1:本地仓库篇

    什么是Git 版本控制系统 首先我们要明白,什么是版本控制系统(version control systems)? 版本控制系统,顾名思义,就是能控制文件处于哪个版本的系统. e.g. 你在博客园里编 ...

  3. Git快速入门进阶篇

    本文接着Git快速入门篇,继续探讨Git在管理项目中的一些应用. 远程仓库的使用 查看远程仓库 查看你已经配置的远程仓库服务器,可以运行 git remote 命令.指定选项 -v,会显示需要读写远程 ...

  4. Git【入门】这一篇就够了

    前言 欢迎关注公众号,白嫖原创PDF,也可以催更,微信搜:JavaPub,回复:[666] Git 在生产工作中是使用频率很高的工具,但我发现很多文章只是对它做了简单的提交命令说明,真正遇到 版本冲突 ...

  5. Git入门仅这篇就够了

    版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com/cavalier-/p/5978937.html 前言 大家好,我是Cavalier ...

  6. git快速入门 push/clone/reset/merge/切换分支全都有

    本文介绍git快速入门,从安装/创建init / 发布push/版本回退reset / branch分支切换/合并分支merge 这些基本的操作都有涉及,方便新人快速入手,有需要的朋友mark一下.首 ...

  7. 从零开始使用git第三篇:git撤销操作、分支操作和常见冲突

    从零开始使用git 第三篇:git撤销操作.分支操作和常见冲突 第一篇:从零开始使用git第一篇:下载安装配置 第二篇:从零开始使用git第二篇:git实践操作 第三篇:从零开始使用git第三篇:gi ...

  8. 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳

    学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 ...

  9. 学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳

    学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 10 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳 ...

随机推荐

  1. PHP 获取重复数组中 第二多的元素

    $target = ["重复项目", "repeat", "repeat", "重复", "重复项目" ...

  2. 【Java基础】基本语法-变量与运算符

    基本语法-变量与运算符 关键字和保留字 关键字定义:被 Java 语言赋予了特殊含义,用做专门用途的字符串(单词). 关键字特点:关键字中所有字母都为小写. 用于定义数据类型:class.interf ...

  3. LeetCode542 01矩阵

    给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 0 1 0 0 0 ...

  4. [工作札记]02: .Net Winform控件TreeView最简递归绑定方法

    前言:Treeview控件是我们在WinForm.WebForm开发中经常使用的控件,需要从数据库动态加载数据,然后递归绑定每一个节点:同样,递归的思路在其他程序中也经常运用,包括.Net MVC等. ...

  5. Maven学习笔记之第一个Maven项目(Linux)

    Maven是Apache旗下的管理Java项目jar包的项目管理工具,有了它可以很方便构建和管理我们的Java项目,你不必在互联网上逐个查找你需要的第三方jar包,你只需在maven reposito ...

  6. git revert 回退已经push的内容

    如题,在日常的开发过程中,可能有组员不小心一下子吧文件修改,需要进行回退 回退主要涉及到2种命令,一种是git reset 一种是 git revert git reset 会修改git log提交历 ...

  7. 【EXP】WINDOWS下如何导出

    有些时候需要在windows下通过远程来导出数据 那么windows下怎么导出呢 例子: exp hr/hr@192.168.1.222:1521/zhang file=d:backup.dmp lo ...

  8. Golang应用性能问题排查分析

    背景 公司有一个使用golang开发的采集模块,负责调用多个外部系统采集数据:最近做了一次架构上的调整,将采集模块分成api.job两个子模块,并部署到容器中,拆分前部署在虚机上. 现象 部分采集任务 ...

  9. linux下安装nacos

    一.安装 1.下载安装包: https://github.com/alibaba/nacos/releases 2.解压 : tar -xzvf nacos-server-1.2.1.tar.gz 3 ...

  10. openshift 3.11安装部署

    openshift 3.11 安装部署 openshift安装部署 1 环境准备(所有节点) openshift 版本 v3.11 1.1 机器环境 ip cpu mem hostname OSsys ...