Git 分支的创建与切换

文章目录

  • Git 分支的创建与切换
    • Git 分支的本质
    • 分支创建
    • 分支切换
    • 参考资料

几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响主线的开发。 在很多版本控制系统中,这是一个略微低效的过程 —— 常常需要完全创建一个源代码目录的副本。对于大项目来说,这样的过程会耗费很多时间。

有人把 Git 的分支模型称为它的“必杀技特性”,也正是因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。 为何 Git 的分支模型如此出众呢? Git 处理分支的方式可谓是超级轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间切换也是一样便捷。

与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并。理解和精通这一特性,你便会意识到 Git 是如此强大而又独特,并且从此真正改变你的开发方式。

Git 分支的本质

Git 的分支,其本质上仅仅是指向提交对象的可变指针。说它“可变”是因为它会在每次的提交操作中自动向前移动。 Git 的默认分支名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。

Git 的 “master” 分支并不是一个特殊分支。 它跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数人都懒得去改动它。

分支创建

Git 是怎么创建新分支的呢? 很简单,它只是为你创建了一个可以移动的新的指针。 比如,创建一个 testing 分支, 你需要使用 git branch 命令:

$ git branch testing

这会在当前所在的提交对象上创建一个指针。

那么,Git 又是怎么知道当前在哪一个分支上呢? 也很简单,它有一个名为 HEAD 的特殊指针。

请注意它和许多其它版本控制系统(如 Subversion 或 CVS)里的 HEAD 概念完全不同。 在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。 在本例中,你仍然在 master 分支上。 因为 git branch 命令仅仅创建一个新分支,并不会自动切换到新分支上去。

你可以简单地使用 git log 命令查看各个分支当前所指的对象。 提供这一功能的参数是 --decorate

$ git log --oneline --decoratef30ab (HEAD -> master, testing) add feature #32 - ability to add new
34ac2 fixed bug #1328 - stack overflow under certain conditions
98ca9 initial commit of my project

正如你所见,当前 “master” 和 “testing” 分支均指向校验和以 f30ab 开头的提交对象,且当前在 master 分支(因为 HEAD 指向 master)。

分支切换

要切换到一个已存在的分支,你需要使用 git checkout 命令。 现在切换到新创建的 testing 分支去:

$ git checkout testing

这样 HEAD 就指向 testing 分支了。

那么,切换分支会给我们带来什么影响呢? 现在不妨再提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'

提交后的示意图如下:

看到了吗?你的 testing 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象。 这就有意思了,现在我们切换回 master 分支看看:

$ git checkout master

这条命令做了两件事。 一是使 HEAD 指回 master 分支,二是将工作目录恢复成 master 分支所指向的快照内容。 也就是说,你现在做修改的话,项目将始于一个较旧的版本(f30ab)。 本质上来讲,这就是忽略 testing 分支所做的修改,以便于向另一个方向进行开发。

分支切换会改变你工作目录中的文件

在切换分支时,一定要注意你工作目录里的文件会被改变。 如果是切换到一个较旧的分支,你的工作目录会恢复到该分支最后一次提交时的样子。 如果 Git 不能干净利落地完成这个任务,它将禁止切换分支。

我们不妨再做些修改并提交:

$ vim test.rb
$ git commit -a -m 'made other changes'

现在,这个项目的提交历史已经产生了分叉。 因为刚才你创建了一个新分支,并切换过去进行了一些工作,随后又切换回 master 分支进行了另外一些工作。

你可以简单地使用 git log 命令查看分叉历史。 运行git log --oneline --decorate --graph--all ,它会输出你的提交历史、各个分支的指向以及项目的分支分叉情况。

$ git log --oneline --decorate --graph --all
* c2b9e (HEAD -> master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project

由于 Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都非常高效。 创建一个新分支就相当于往一个文件中写入 41 个字节(40 个字符和 1 个换行符),如此之简单能不快吗?

这与过去大多数版本控制系统形成了鲜明的对比:它们在创建分支时,将所有的项目文件都复制一遍,并保存到一个特定的目录。 完成这样繁琐的过程通常需要好几秒钟,有时甚至需要好几分钟。所需时间的长短,完全取决于项目的规模。而在 Git 中,任何规模的项目都能在瞬间创建新分支。


参考资料

《Pro Git》(Scott Chacon, Ben Straub Version 2.1.14, 2018-05-19)

Git 分支的创建与切换 —— Git 学习笔记 14相关推荐

  1. git 分支的创建和切换

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

  2. Git分支的创建,切换及分支指针移动的理解

    分支的掌握和理解到位对于我们工作中的并行开发十分重要,今天我们一起来研究它. 一,两人在一个分支上开发 程序员小王入职,拉取了仓库的代码,开发新需求. git clone https://github ...

  3. 【Git】Git 分支管理 ( 创建并切换分支 | 查看分支 git branch | 合并分支 git merge dev | 删除分支 git branch -d dev )

    文章目录 一.创建并切换分支 1.创建分支 git branch dev 2.切换分支 git checkout dev 3.创建并切换分支 git checkout -b dev 二.查看分支 gi ...

  4. git reset后本地拉取_Git学习笔记

    git工作区和本地仓库 创建本地版本库 mkdir learnGitcd learnGitgit init 添加到暂存区 touch learn.mdopen learn.mdgit add lear ...

  5. Git、Github、Gitee、GitLab学习笔记

    文章目录 Git.Github.Gitee.GitLab学习笔记 前言 一.Git 1.Git概述 2.Git基本操作介绍 2.1 安装&卸载 2.2 启动 3.Git的基本使用 3.1 GI ...

  6. Git最新教程通俗易懂----狂神说Java -- ---学习笔记

    [狂神说Java]Git最新教程通俗易懂 https://www.bilibili.com/video/BV1FE411P7B3 P1.前言之版本控制 06:12 P2.Git和SVN的区别 07:3 ...

  7. Java中如何创建自定义的注解学习笔记(MD版)

    概要 Java中如何创建自定义的注解学习笔记(MD版). 博客 博客地址:IT老兵驿站. 前言 记得这篇笔记还是在泉州的龙玲酒店记录的,是一个周六的晚上,坐飞机从上海到泉州,从笔记中能勾起一些旅游的回 ...

  8. 华为HCIA-datacom 学习笔记14——WLAN概述

    华为HCIA-datacom 学习笔记14--WLAN概述 1.WLAN(无线局域网) 通过无线技术构造的无线局域网络.WLAN广义上是指以无线电波.激光.红外线等无线信号代替有线局域网中的部分或全部 ...

  9. 【转】 C#学习笔记14——Trace、Debug和TraceSource的使用以及日志设计

    [转] C#学习笔记14--Trace.Debug和TraceSource的使用以及日志设计 Trace.Debug和TraceSource的使用以及日志设计   .NET Framework 命名空 ...

最新文章

  1. mysql数据库优化(二)
  2. 通过FM CO_VB_ORDER_POST更新生产订单的Components数据
  3. 2020“高教社”杯全国大学生数学建模竞赛——建模国赛优秀论文
  4. java去除json 转移,Spring MVC返回的json去除根节点名称的方法
  5. 在.NET Core下的机器学习--学习笔记
  6. LaTeX双栏模板插入通栏公式(跨栏插图)
  7. Javascript基础之-原型(prototype)
  8. mongod启动问题
  9. [BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)
  10. docker 错误:Error response from daemon: cannot stop container: connect: connection refused: unknown...
  11. blazeds_Spring BlazeDS集成:它是什么,它会发生什么变化?
  12. Android studio 设置签名
  13. 网络故障排查的思路和方法
  14. 计算机网络教程第5版-第1章计算机网络概述
  15. layer的move要怎么用
  16. 条件运算符与条件if的姻缘,打擂台算法和大小写字母转换,if逻辑避坑
  17. 老年计算机班教案,山东老年大学课程好潮!摄影电脑智能手机班人气爆棚
  18. AI技术内参021-SIGIR2018论文精读:如何对搜索页面上的点击行为进行序列建模?
  19. cuda编程与gpu并行计算(六):图稀疏矩阵转为CSR结构并传入gpu
  20. 关于深度可分离卷积 Depthwise Pointwise Convolution

热门文章

  1. LeetCode第一刷--leetcode提交格式介绍与273. Integer to English Words
  2. DML触发器实现日志功能
  3. java之hiberante之集合映射之list映射
  4. 剑指Offer(书):链表的倒数第K个节点
  5. Lucene实战之基于StandardAnalyzer读写索引
  6. UVA 1151 Buy or Build MST(最小生成树)
  7. [转]避免PHP-FPM内存泄漏导致内存耗尽
  8. 公安部:明年起闯红灯扣6分 挡车牌扣12分
  9. iOS 转换BGR24 为 RGB24
  10. 浅谈Python和VC中的编码问题(转)