0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

通俗易懂的Git各指令的本质

数据分析与开发 来源:掘金 作者: Bezier 2021-06-24 18:06 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

0前言

作为当前世界上最强大的代码管理工具Git相信大家都很熟悉,但据我所知有很大一批人停留在clone、commit、pull、push.。。的阶段,是不是对rebase心里没底只敢用merge?

碰见版本回退就抓瞎?别问我怎么知道的,问就是:“我曾经就是这样啊~~”。

针对这些问题,今天我就将这几年对Git的认知和理解分享出来,尽可能的从本质去讲解Git,帮助你一步一步去了解Git的底层原理,相信读完本篇文章你便可以换种姿态,更加风骚得使用Git各种指令。

1基本概念

1.1 Git的优势

Git是一个分布式代码管理工具,在讨论分布式之前避免不了提及一下什么是中央式代码管理仓库

中央式:所有的代码保存在中央服务器,所以提交必须依赖网络,并且每次提交都会带入到中央仓库,如果是协同开发可能频繁触发代码合并,进而增加提交的成本和代价。最典型的就是svn

分布式:可以在本地提交,不需要依赖网络,并且会将每次提交自动备份到本地。每个开发者都可以把远程仓库clone一份到本地,并会把提交历史一并拿过来。代表就是Git

那Git相比于svn有什么优势呢?

打个比方:“巴拉巴拉写了一大堆代码,突然发现写的有问题,我想回到一个小时之前”,对于这种情况Git的优势就很明显了,因为commit的成本比较小并且本地会保存所有的提交记录,随时随刻可以进行回退。

在这并不是说svn的不能完成这种操作,只是Git的回退会显得更加的优雅。Git相比于中央式工具还有很多优点,就不一一列举了,感兴趣的可自行了解。

1.2 文件状态

在Git中文件大概分为三种状态:已修改(modified)、已暂存(staged)、已提交(committed)

修改:Git可以感知到工作目录中哪些文件被修改了,然后把修改的文件加入到modified区域

暂存:通过add命令将工作目录中修改的文件提交到暂存区,等候被commit

提交:将暂存区文件commit至Git目录中永久保存

1.3 commit节点

为了便于表述,本篇文章我会通过节点代称commit提交

在Git中每次提交都会生成一个节点,而每个节点都会有一个哈希值作为唯一标示,多次提交会形成一个线性节点链(不考虑merge的情况)。

节点上方是通过 SHA1计算的哈希值

C2节点包含C1提交内容,同样C3节点包含C1、C2提交内容

1.4 HEAD

HEAD是Git中非常重要的一个概念,你可以称它为指针或者引用,它可以指向任意一个节点,并且指向的节点始终为当前工作目录,换句话说就是当前工作目录(也就是你所看到的代码)就是HEAD指向的节点。

还以图1-1举例,如果HEAD指向C2那工作目录对应的就是C2节点。具体如何移动HEAD指向后面会讲到,此处不要纠结。

同时HEAD也可以指向一个分支,间接指向分支所指向的节点。

1.5 远程仓库

虽然Git会把代码以及历史保存在本地,但最终还是要提交到服务器上的远程仓库。通过clone命令可以把远程仓库的代码下载到本地,同时也会将提交历史、分支、HEAD等状态一并同步到本地,但这些状态并不会实时更新,需要手动从远程仓库去拉取,至于何时拉、怎么拉后面章节会讲到。

通过远程仓库为中介,你可以和你的同事进行协同开发,开发完新功能后可以申请提交至远程仓库,同时也可以从远程仓库拉取你同事的代码。

注意点

因为你和你的同事都会以远程仓库的代码为基准,所以要时刻保证远程仓库的代码质量,切记不要将未经检验测试的代码提交至远程仓库

2分支

2.1 什么是分支?

分支也是Git中相当重要的一个概念,当一个分支指向一个节点时,当前节点的内容即是该分支的内容,它的概念和HEAD非常接近同样也可以视为指针或引用,不同的是分支可以存在多个,而HEAD只有一个。通常会根据功能或版本建立不同的分支。

那分支有什么用呢?

举个例子:你们的 App 经历了千辛万苦终于发布了v1.0版本,由于需求紧急v1.0上线之后便马不停蹄的开始v1.1,正当你开发的兴起时,QA同学说用户反馈了一些bug,需要修复然后重新发版,修复v1.0肯定要基于v1.0的代码,可是你已经开发了一部分v1.1了,此时怎么搞?

面对上面的问题通过引入分支概念便可优雅的解决。

先看左边示意图,假设C2节点既是v1.0版本代码,上线后在C2的基础上新建一个分支ft-1.0

再看右边示意图,在v1.0上线后可在master分支开发v1.1内容,收到QA同学反馈后提交v1.1代码生成节点C3,随后切换到ft-1.0分支做bug修复,修复完成后提交代码生成节点C4,然后再切换到master分支并合并ft-1.0分支,到此我们就解决了上面提出的问题

除此之外利用分支还可以做很多事情,比如现在有一个需求不确定要不要上线,但是得先做,此时可以单独创建一个分支开发该功能,等到啥时候需要上线直接合并到主分支即可。分支适用的场景很多就不一一列举了。

注意点

当在某个节点创建一个分支后,并不会把该节点对应的代码复制一份出来,只是将新分支指向该节点,因此可以很大程度减少空间上的开销。一定要记着不管是HEAD还是分支它们都只是引用而已,量级非常轻

3命令详解

3.1 提交相关

前面我们提到过,想要对代码进行提交必须得先加入到暂存区,Git中是通过命令 add 实现

添加某个文件到暂存区:

git add 文件路径

添加所有文件到暂存区:

git add 。

同时Git也提供了撤销工作区和暂存区命令

撤销工作区改动:

git checkout -- 文件名

清空暂存区:

git reset HEAD 文件名

提交:

将改动文件加入到暂存区后就可以进行提交了,提交后会生成一个新的提交节点,具体命令如下:

git commit -m “该节点的描述信息”

3.2 分支相关

创建分支

创建一个分支后该分支会与HEAD指向同一节点,说通俗点就是HEAD指向哪创建的新分支就指向哪,命令如下:

git branch 分支名

切换分支

当切换分支后,默认情况下HEAD会指向当前分支,即HEAD间接指向当前分支指向的节点

git checkout 分支名

同时也可以创建一个分支后立即切换,命令如下:

git checkout -b 分支名

删除分支

为了保证仓库分支的简洁,当某个分支完成了它的使命后应该被删除。比如前面所说的单独开一个分支完成某个功能,当这个功能被合并到主分支后应该将这个分支及时删除。

删除命令如下:

git branch -d 分支名

3.3 合并相关

关于合并的命令是最难掌握同时也是最重要的。我们常用的合并命令大概有三个merge、rebase、cherry-pick

merge

merge是最常用的合并命令,它可以将某个分支或者某个节点的代码合并至当前分支。具体命令如下:

git merge 分支名/节点哈希值

如果需要合并的分支完全领先于当前分支。

由于分支ft-1完全领先分支ft-2即ft-1完全包含ft-2,所以ft-2执行了“git merge ft-1”后会触发fast forward(快速合并),此时两个分支指向同一节点,这是最理想的状态。

这种情况就不能直接合了,当ft-2执行了“git merge ft-1”后Git会将节点C3、C4合并随后生成一个新节点C5,最后将ft-2指向C5 如图3-2(右)

注意点:

如果C3、C4同时修改了同一个文件中的同一句代码,这个时候合并会出错,因为Git不知道该以哪个节点为标准,所以这个时候需要我们自己手动合并代码

rebase

rebase也是一种合并指令,命令行如下:

git rebase 分支名/节点哈希值

与merge不同的是rebase合并看起来不会产生新的节点(实际上是会产生的,只是做了一次复制),而是将需要合并的节点直接累加。

ft-1.0执行了git rebase master后会将C4节点复制一份到C3后面,也就是C4‘,C4与C4’相对应,但是哈希值却不一样。

rebase相比于merge提交历史更加线性、干净,使并行的开发流程看起来像串行,更符合我们的直觉。既然rebase这么好用是不是可以抛弃merge了?其实也不是了,下面我罗列一些merge和rebase的优缺点:

merge优缺点:

优点:每个节点都是严格按照时间排列。当合并发生冲突时,只需要解决两个分支所指向的节点的冲突即可

缺点:合并两个分支时大概率会生成新的节点并分叉,久而久之提交历史会变成一团乱麻

rebase优缺点:

优点:会使提交历史看起来更加线性、干净

缺点:虽然提交看起来像是线性的,但并不是真正的按时间排序,比如图3-3中,不管C4早于或者晚于C3提交它最终都会放在C3后面。并且当合并发生冲突时,理论上来讲有几个节点rebase到目标分支就可能处理几次冲突

对于网络上一些只用rebase的观点,作者表示不太认同,如果不同分支的合并使用rebase可能需要重复解决冲突,这样就得不偿失了。但如果是本地推到远程并对应的是同一条分支可以优先考虑rebase。所以我的观点是 根据不同场景合理搭配使用merge和rebase,如果觉得都行那优先使用rebase

cherry-pick

cherry-pick的合并不同于merge和rebase,它可以选择某几个节点进行合并,如图3-4

命令行:

git cherry-pick 节点哈希值

假设当前分支是master,执行了git cherry-pick C3(哈希值),C4(哈希值)命令后会直接将C3、C4节点抓过来放在后面,对应C3‘和C4’

3.4 回退相关

分离HEAD

在默认情况下HEAD是指向分支的,但也可以将HEAD从分支上取下来直接指向某个节点,此过程就是分离HEAD,具体命令如下:

git checkout 节点哈希值

//也可以直接脱离分支指向当前节点

git checkout --detach

由于哈希值是一串很长很长的乱码,在实际操作中使用哈希值分离HEAD很麻烦,所以Git也提供了HEAD基于某一特殊位置(分支/HEAD)直接指向前一个或前N个节点的命令,也即相对引用,如下:

//HEAD分离并指向前一个节点

git checkout 分支名/HEAD^

//HEAD分离并指向前N个节点

git checkout 分支名~N

将HEAD分离出来指向节点有什么用呢?举个例子:如果开发过程发现之前的提交有问题,此时可以将HEAD指向对应的节点,修改完毕后再提交,此时你肯定不希望再生成一个新的节点,而你只需在提交时加上--amend即可,具体命令如下:

git commit --amend

回退

回退场景在平时开发中还是比较常见的,比如你巴拉巴拉写了一大堆代码然后提交,后面发现写的有问题,于是你想将代码回到前一个提交,这种场景可以通过reset解决,具体命令如下:

//回退N个提交

git reset HEAD~N

reset和相对引用很像,区别是reset会使分支和HEAD一并回退。

3.5 远程相关

当我们接触一个新项目时,第一件事情肯定是要把它的代码拿下来,在Git中可以通过clone从远程仓库复制一份代码到本地,具体命令如下:

git clone 仓库地址

前面的章节我也有提到过,clone不仅仅是复制代码,它还会把远程仓库的引用(分支/HEAD)一并取下保存在本地,如图3-5所示:

其中origin/master和origin/ft-1为远程仓库的分支,而远程的这些引用状态是不会实时更新到本地的,比如远程仓库origin/master分支增加了一次提交,此时本地是感知不到的,所以本地的origin/master分支依旧指向C4节点。我们可以通过fetch命令来手动更新远程仓库状态

小提示:

并不是存在服务器上的才能称作是远程仓库,你也可以clone本地仓库作为远程,当然实际开发中我们不可能把本地仓库当作公有仓库,说这个只是单纯的帮助你更清晰的理解分布式

fetch

说的通俗一点,fetch命令就是一次下载操作,它会将远程新增加的节点以及引用(分支/HEAD)的状态下载到本地,具体命令如下:

git fetch 远程仓库地址/分支名

pull

pull命令可以从远程仓库的某个引用拉取代码,具体命令如下:

git pull 远程分支名

其实pull的本质就是fetch+merge,首先更新远程仓库所有状态到本地,随后再进行合并。合并完成后本地分支会指向最新节点

另外pull命令也可以通过rebase进行合并,具体命令如下:

git pull --rebase 远程分支名

push

push命令可以将本地提交推送至远程,具体命令如下:

git push 远程分支名

如果直接push可能会失败,因为可能存在冲突,所以在push之前往往会先pull一下,如果存在冲突本地解决。push成功后本地的远程分支引用会更新,与本地分支指向同一节点。

综上所述

不管是HEAD还是分支,它们都只是引用而已,引用+节点是 Git 构成分布式的关键

merge相比于rebase有更明确的时间历史,而rebase会使提交更加线性应当优先使用

通过移动HEAD可以查看每个提交对应的代码

clone或fetch都会将远程仓库的所有提交、引用保存在本地一份

pull的本质其实就是fetch+merge,也可以加入--rebase通过rebase方式合并

作者:掘金-Bezier

链接:https://juejin.cn/post/6895246702614806542

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4975

    浏览量

    74349
  • SHA
    SHA
    +关注

    关注

    0

    文章

    19

    浏览量

    8767
  • Git
    Git
    +关注

    关注

    0

    文章

    207

    浏览量

    17045

原文标题:Git 各指令的本质,真是通俗易懂啊

文章出处:【微信号:DBDevs,微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    ​UPS电源变压全解析:工频与高频核心差异,选型不踩坑

    ,其实二者的核心区别,本质就是变压逻辑的不同。今天就来全面拆解UPS电源的变压原理、关键环节与选型技巧,通俗易懂,新手也能快速get核心要点。先明确一个核心认知:UP
    的头像 发表于 03-05 10:05 295次阅读
    ​UPS电源变压全解析:工频与高频核心差异,选型不踩坑

    使用诺顿定理的等效电路分析

    本文将从诺顿定理的基本原理、具体求解方法,到与其他分析方法的区别,进行通俗易懂的介绍。同时,也将对诺顿定理的使用要点进行整理归纳。
    的头像 发表于 12-10 13:59 4799次阅读
    使用诺顿定理的等效电路分析

    通俗易懂的晶振专业术语

    想要了解一个行业,就要对其产品的术语要有所了解,各行各业都要自己专业术语,石英晶振也不例外;了解晶振术语对晶振采购和选型有很大帮助;下面小扬给大家简单的解释晶振术语都代表什么意思:
    的头像 发表于 09-18 11:31 2118次阅读
    <b class='flag-5'>通俗易懂</b>的晶振专业术语

    普通扫码枪和手持扫码PDA的功能对比:哪个更适合你的行业?

    本文深入了解手持PDA与扫码枪的专业区别、核心功能、应用场景及选购要点。本文将通过通俗易懂的语言,助您清晰区分这两种数据采集设备,并为您的业务选择最合适的解决方案。
    的头像 发表于 09-02 14:37 1426次阅读
    普通扫码枪和手持扫码PDA的功能对比:哪个更适合你的行业?

    【「DeepSeek 核心技术揭秘」阅读体验】--全书概览

    感谢平台提供的书籍,实物如下 这本书主讲从年前开始火热的DeepSeek 。书籍看起来轻薄,但言简意赅,通俗易懂,总览全局,比较精炼。 第一章 介绍DeepSeek的一系列技术突破与创新。 第二章
    发表于 07-21 00:04

    LED驱动电路设计

    兼顾了不同读者的需要,由浅入深,层次清晰,通俗易懂,实用性强,可作为电气工程类专业本科生及研究生的入门教材,也可供从事LED驱动电源设计的工程技术人员参考。获取完整文档资料可下载附件哦!!!! 如果内容有帮助可以关注、点赞、评论支持一下哦~
    发表于 07-18 15:26

    通俗易懂版)排针的作用和生产加工中对温度的要求

    总结: 排针注塑加工时温度过高,本质是过度加热带来的连锁反应: 1. 伤“密封”(塑料变形老化) -> 造成泄漏。 2. 卡“筋骨”(塑料/金属热胀冷缩不均) -> 针脚卡死
    的头像 发表于 06-27 17:34 2768次阅读
    (<b class='flag-5'>通俗易懂</b>版)排针的作用和生产加工中对温度的要求

    图解单片机功能与应用(完整版)

    过程通道图解、单片机显示电路图解、51单片机按键识别电路图解、51单片机常用算法图解、单片机常用电路图解、51单片机抗扰技术图解、51单片机典型应用案例图解。书中注重基础,强调应用,内容充实,通俗易懂,例举
    发表于 06-16 16:52

    单片机C语言入门指导(非常通俗易懂!)

    (一) 相信很多爱好电子的朋友,对单片机这个词应该都不会陌生了吧。不过有些朋友可能只 听说他叫单片机,他的全称是什么也许并不太清楚, 更不用说他的英文全称和简称了。单片机是一块在集成电路芯片上集成了一台有一定规模的 微型计算机。简称为:单片微型计算机或单片机 (Single Chip Computer)。单片机的应用到处可见,应用领域广泛,主要应用在智能仪表、 实时控制、通信、家电等方面。不过这一切都没什么关系,因为我(当然也包括任何人)都是从不知道转变成知道的,再转变成精通的。 现在我只想把我学习单片机的经历,详细地讲叙给大 家听听,可能有些大虾会笑话我,想:那么简单的东西还在这里卖弄。但是你错了,我只是 把我个人学习的经历讲述一遍而已,仅仅对那些想 学习单片机,但又找不到好方法或者途径的朋友,提供一个帮助,使他们在学习过程中,尽 量少走些弯路而已!首先,你必须有学习单片机的热情, 不是说今天去图书馆看了一个下午关于单片机的书, 而明天玩上半天,后天就不知道那个本书在讲什 么东西了。 还是先说说我吧,我从大二的第一个学期期末的时候才开始接触单片机,但在这之前,正如上面所说的:我知道有种芯片叫单片机, 但是具体长成什么样子,却一点也不知道!看到这里很多朋友一定会忍不住发笑。嘿嘿,你 可千万别笑,有些大四毕业的人也同样不知道单片 机长成什么样子呢!而我对单片机的痴迷更是常人所不能想象的地步,大二的期末考试,我全放弃了复习,每当室友拿着书在埋头复习的时候, 我却捧着自己从图书馆借的单片机书在那看,虽然有很多不懂,但是我还是坚持了下来,当 时我就想过,为了单片机值不值得我这样去付出,或许这也是在一些三流学校的好处吧,考试挂科后,明年开学交上几十元一门的补考费,应 该大部分都能过了。于是,我横下一条心,坚持看 我的单片机书和资料。 当你明白了单片机是这么一回事的时候, 显而易见的问题出来了: 我要选择那种语言为 单片机编写程序呢? 这个问题,困扰了我好久。具 体选择 C51 还是 A51 呢?汇编在我们大二之前并没有开过课, 虽然看着人家的讲解, 很容易 明白单片机的每一时刻的具体工作情况,但是一合上 书或者资料,自己却什么也不知道了,根本不用说自己写程序了。于是,我最终还是决定学 C51,毕竟 C51 和我们课上讲的 C 语言,有些类似, 编程的思想可以说是相通的。 而且 C51 还有更大的优点就是编写大程序时的优越性更不言而 喻,当然在那时,我并没有想的那么深远,C51 的特 点,还是在后来的实践过程中,渐渐体会到的!朋友如果你选择了 C51,那么请继续往下看, 如果你选择了 A51,那么你可以不要看了!因为下面讲 的全是 C 方面的,完全在浪费你的时间! 获取完整文档资料可下载附件哦!!!! 如果内容有帮助可以关注、点赞、评论支持一下哦~
    发表于 06-16 16:32

    边缘计算服务器全面解析:为什么5G、AI、工业智造都绕不开它?

    说起“边缘计算服务器”,很多人第一反应是:这是服务器的一种吧?是的,但它远不止“服务器的一种”这么简单。今天,小颉就从一个行业专业从业者的角度,用通俗易懂的语言,聊聊这个在5G、AI和工业现场大显身手的硬核选手——边缘计算服务器。
    的头像 发表于 06-03 16:34 1115次阅读
    边缘计算服务器全面解析:为什么5G、AI、工业智造都绕不开它?

    电路基础学习资料

    不可多得的电路基础知识学习资料,作者郝铭先生具有深厚的电路功底,且讲解的非常通俗易懂,非常适合初学者。 纯分享贴,有需要可以直接下载附件获取完整资料! (如果内容有帮助可以关注、点赞、评论支持一下哦~)
    发表于 05-17 15:01

    常用电器控制电路精选

    电器控制电路,定时器、温控、门铃及密码控制电路。这些电路,对于电路设计人员、相关专业学生及电子爱好者都有一定的参考价值。书中所有电路均按电路工作 原理、元器件选用顺序进行介绍,语言通俗易懂,形式图文并茂,具有
    发表于 05-14 16:59

    电源模块PCB设计注意事项

    PCB设计的基础入门教材,图文并茂,通俗易懂 纯分享贴,有需要可以直接下载附件获取完整资料! (如果内容有帮助可以关注、点赞、评论支持一下哦~)
    发表于 05-06 15:43

    秒懂CCC与CQC,别傻傻分不清啦

    通俗易懂说CCC与CQC
    的头像 发表于 05-06 10:23 9447次阅读
    秒懂CCC与CQC,别傻傻分不清啦

    TCP三次握手和四次挥手,这样解释太通俗易懂了!

    TCP连接的建立和释放分别通过“三次握手”和“四次挥手”来完成。三次握手过程TCP三次握手是建立可靠网络连接的关键过程,它用于确保通信双方能够正常发送和接收数据,并提供可靠的数据传输机制。三次握手的主要目标包括:•同步双方的序列号•确认双方的接收和发送能力•防止因为过期报文导致的误连接1第一次握手•客户端发送一个SYN(同步)请求报文,表示希望建立连接,并附
    的头像 发表于 04-24 19:33 1668次阅读
    TCP三次握手和四次挥手,这样解释太<b class='flag-5'>通俗易懂</b>了!