什么是分支

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

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会找到 C3 和 C4 的共同祖先 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.txt 的 C5 。

遇到冲突时的合并

有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个文件进行了不同的修改,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. 修改postman工具的代码生成工具让它锦上添花

    @font-face { font-family: octicons-link; src: url("data:font/woff;charset=utf-8;base64,d09GRgAB ...

  2. 【剑指 Offer】10-I.斐波那契数列

    题目描述 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项.斐波那契数列的定义如下: F(0) = 0,   F(1) = 1 F(N) = F(N - 1) + F(N - ...

  3. 实现一个简单的 Linux Shell(C++)

    Implement a simple command interpreter in Linux. The interpreter should: support both internal and e ...

  4. requests+BeautifulSoup | 爬取电影天堂全站电影资源

    import requests import urllib.request as ur from bs4 import BeautifulSoup import csv import threadin ...

  5. 【Java】集合框架(List Set Map)

    文章目录 集合框架 List(列表) ArrayList 案例 Set HashSet 案例 iterator(迭代器) Map HashMap 案例 集合总结 参考资料 重新搞一波 复习巩固 简单记 ...

  6. canvas多重阴影发光效果

    canvas多重阴影发光效果 前言 在一个项目中,客户提了一个发光的效果,效果图如下: 阴影 有的人可能会说,这个用阴影其实就可以实现.但是从图中可以看出,是一个比较强烈的发光效果.实际的应用过程中我 ...

  7. DG主备切换遇到not allwod或者RESOLVABLE GAP解决办法

    今天做switchover,环境是11.2.0.3+OEL5.7,开始时主备库状态都是正常的,符合直接切换条件: 主库: SQL> select open_mode,database_role, ...

  8. 【Oracle】静默安装oracle 11.2.0.4 超详细

    安装oracle 1.执行脚本完成初始化oracle环境 2.解压缩oracle的压缩包,单实例1个,rac是2两个压缩包 3.修改response下的db_install.rsp 修改内容如下: - ...

  9. EF Core 6.0的新计划

    今天,我们很兴奋地与你分享Entity Framework Core 6.0的计划. 这个计划汇集了许多人的意见,并概述了我们打算在哪里以及如何优化实体框架(EF Core) 6.0版本.这个计划并不 ...

  10. 【葵花宝典】一天掌握Kubernetes

    1.kubernetes介绍 kubernetes,简称K8s,是用8代替8个字符"ubernete"而成的缩写.是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kuber ...