g4e基础篇#6 了解Git历史记录

Git的版本历史记录采用了与传统集中式版本管理系统完全不同的方式进行组织,在刚开始使用Git的时候我们往往会不知所措,比如看到这样的历史记录。

看到这个七拐八拐的图形,你可能完全不知道它代表了什么。其实这正是Git的特别之处,Git之所以能够实现之前我们所说那些灵活快速的操作,都是因为它采用这种类似链路的版本记录方式。在这一篇中,我们就一起了解一下这个图形是如何生成的。

这里,我们要模拟一个常见的开发场景:

  • 你正在开发一个网站的某个新功能,按照Git的推荐方式,你创建了feature1分支来承载这个新功能的代码变更。

  • 当你已经在这个功能上完成几次代码提交的时候,你的项目经理告诉你这个网站现在出现了一个严重的线上问题,需要紧急修复。

  • 为了能够快速修复这个线上问题,你不能等待下一个版本发布,必须在现有线上版本上进行修复。这时你暂停了feature1分支的开发工作,切换回到master分支,从新拉取一个名为hotfix的分支并在这个分支上开始了线上问题的修复。

  • 当你完成了修复并测试通过后,你将hotfix分支合并到master以便立即从新发布线上版本。

  • 完成以上工作后,你切换回到feature1分支继续进行新功能的开发直到新的功能也经过测试可以发布。

  • 最后你将feature1分支也合并回到master分支,发布到线上环境。

为了演示这个过程,首先我使用 Visual Studio 创建了一个新的Web网站项目,完成了4次提交并推送到了TFS的Git仓库。

初始状态

初始的历史记录显示如下:

用简单的示意图表示,是这样的:

如果使用命令行查看历史记录可以键入如下命令

>>> git log --oneline --graph

以上的–oneline参数让git只输出第一行的注释信息,简化历史记录更加可读;–graph参数用来在命令行中输出图形链路,现在我们还看不到效果,后面就会有变化。

输出的结果如下

注:如果你在使用以上命令的过程中遇到乱码,请参考:常见问题#4

这表示当前的master分支指向版本库最新的一次提交(C4),同时之前的所有提交都是顺序完成的,形成了一个单一主线的链路。在TFS的版本记录视图上你所看到的图形一列表示的是同一个意思。

创建feature1分支并提交2次变更

现在,按照我们在上一篇中介绍的方法,创建feature1分支,并在这上面完成2次新的提交。

此时再次使用上面的命令列出历史记录,你会看到如下结果:

这个时候你就会有点纳闷了,为什么明明做了分支,历史记录仍然是单一的直线呢?不是应该分叉了吗?看一下示意图你就明白了。

Git确实记录了你的分支信息,只不过它非常聪明的只是修改了feature1所指向的提交而已;这时你的master分支仍然指向C4提交,而feature1分支则指向C6提交了。

以上git log所输出的信息中也非常明确的标明了这一点,看一下历史记录的第1行和第3行括号里面内容就明白了。

创建hotfix分支并提交另外2次变更

现在那个讨厌的项目经理给你下达了新的任务,要修复线上问题。因为线上所部署的正是master分支上的最新版本,所以你需要切换到master分支(也就是C4提交所代表的版本)进行修改。

这时你可以使用以下命令完成hotfix分支的创建

>>> git checkout master
>>> git checkout -b hotfix

完成这个操作后,我们在hotfix分支上输出历史记录。

你会看到现在hotfix和master分支同时指向了一个提交记录(C4),示意图如下:

现在我们在hotfix分支上添加2个新的变更,并输出历史记录

现在hotfix所指向的提交变成了 C8,如果再看我们的示意图就可以看到分叉的效果了

但是为什么git 输出的历史记录中仍然是一条直线呢?这是因为对于master, hotfix和feature1任何一个分支而言,他们的改动对于自己都是单向的唯一链路。

合并hotfix分支到master

现在你已经完成了问题修复,可以将代码合并到master并发布到线上环境了,让我们将hotfix分支的代码合并到master主干上。你需要执行下面命令

>>> git checkout master
>>> git merge hotfix

这2条命令的意思是回到master分支并将hotfix分支的改动合并进来,因为hotfix就是基于master分支进行的,所以合并会直接完成不会有任何的冲突出现。

这里出现了一个词Fast-forward,因为hotfix分支是直接在master分支上完成的,所以git其实仅仅修改了master分支的指向到hotfix的当前指向(也就是C8),输出一下log你就看得很清楚了。

对比刚才在hotfix上的log输出,你会看到这里唯一的变化就是本地master分支的指向移动到了最后一条提交上。你也许会注意到这里还有一个origin/master的指向仍然在之前的提交之上,这时因为我们的Git库已经提交到了TFS的中心存储库,而这个origin/master所代表的是这个中心存储库上的master分支所处的位置,因为我们在以上过程中没有给中心存储库推送过代码,所以这个中心存储库的master分支仍然指向的是最初的位置。

到这里你会明白,Git的分支其实就是一个指针而已,通过这个指针对提交的指向,Git可以非常灵活的切换版本。

到了这里,我们的示意图就变成了这个样子了

合并feature1分支到master分支

现在你已经修复了线上问题,可以回到feature1上继续工作了。假设我们提交C9以后feature1的开发工作也已经完成可以合并了。与刚才合并hotfix的方法一样,我们只需要返回master分支并执行合并命令

>>> git checkout master
>>> git merge feature1

执行的效果如下:

现在如果我们再次在master上输出历史记录,你将看到如下效果

你会注意到git创建了一个新的提交 b5bcb0b 并将这个提交的注释设置为 Merge branch ‘feature1’,它的意思是我为你创建了一个新的提交,在这个提交里面保存了feature1合并进来的代码变更。

注意:在执行merge动作的时候出现了3个Auto-merging的信息,这表明Git自动为你完成了3个文件的合并,在实际使用中这样做可能是会出现问题的,因为Git实际上只是根据文件代码行的信息判断是否可以完成自动合并,这种合并并不是永远安全可靠的。这一点我们在进阶篇中会特别介绍。

现在,我们的示意图就变成了这个样子

最后,我们可以同步代码到TFS中心存储库,并查看服务器上的历史记录。你会看到与我们的示意图非常类似的图形显示。

小结

了解Git处理历史记录的方式对于我们用好Git非常重要,特别是在企业级开发中处理复杂的多版本并行开发的过程中。以上我们提到的几个可能令你困惑的地方,比如hotfix分支合并的时候Git仅仅移动指针的行为,以及最后合并feature1分支时Git创建用于合并的提交的方式都是我们在日常开发中常见的情况。理解了Git的特殊处理方式有助于你在遇到类似情况的时候作出正确的判断,并对后面介绍的很多复杂场景更容易理解。

示例代码:

以上示例代码已经推送到 https://github.com/lean-soft/git-history-demo

相关文章:

原文地址:http://devopshub.cn/2018/01/30/g4e-basic-06-understand-git-history/


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ray框架QA

Orleans与Akka对比,为什么选用Orleans?答: Akka对参与开发的人员要求更高一些,普遍是专家级别,Orleans框架进一步抽象了一层,结合C#语言特性,能普遍降低开发难度。下面是知乎网友的答案,可以参考…

Nacos(三)之架构

转载自 Nacos 架构 基本架构及概念 服务 (Service) 服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务…

ASP.NET Core Razor页面禁用防伪令牌验证

这篇短文中,我将向您介绍如何ASP.NET Core Razor页面中禁用防伪令牌验证。Razor页面是ASP.NET Core 2.0中增加的一个页面控制器框架,用于构建动态的、数据驱动的网站;支持跨平台开发,可以部署到Windows,Unix和Mac操作系…

ASP.NETCore的Kestrel服务器

什么是Kestrel服务器Kestrel是开源的(GitHub提供的源代码),事件驱动的异步I / O服务器,用于在任何平台上托管ASP.NET应用程序。这是一个监听服务器和一个命令行界面。您将侦听服务器安装在Windows或Linux服务器上,并在…

Polly组件对微服务场景的价值

Polly是一个开源框架,在github上可以找到,被善友大哥收录,也是.App vNext的一员!App vNext:https://github.com/App-vNextGitHub:https://github.com/App-vNext/PollyNanoFabric是一个开源的微服务架构,也是善友大哥推荐的:https://github.com/geffzhang/NanoFabric对于NanoFab…

Nacos(七)之Spring Cloud集成

转载自 Nacos Spring Cloud 快速开始 本文主要面向 Spring Cloud 的使用者,通过两个示例来介绍如何使用 Nacos 来实现分布式环境下的配置管理和服务注册发现。 关于 Nacos Spring Cloud 的详细文档请参看:Nacos Config 和 Nacos Discovery。 通过 Nac…

.NET Core 2.1中改进的堆栈信息

. NET Core 2.1 现在具有可读的异步堆栈信息!使得异步、迭代器和字典 ( key not found ) 中的堆栈更容易追踪!这个大胆的主张意味着什么?要知道,为了确定调用 异步 和 迭代器方法的实际重载,(这在以前&…

微软高管解读财报:努力创新云基础架构

2月1日,微软发布了该公司截至2017年12月31日的2018年第二财季财报(即2017年第四季度)。财报显示,微软第二财季营收为289.18亿美元,比上年同期的258.26亿美元增长了12%。受税改与就业法案相关的一次性费用138亿美元的影…

Nacos(九)之Dubbo 融合 Nacos 成为注册中心

转载自 Dubbo 融合 Nacos 成为注册中心 Nacos 作为 Dubbo 生态系统中重要的注册中心实现,本文将会介绍如何进行 Dubbo 对接 Nacos 注册中心的工作。 预备工作 请确保后台已经启动 Nacos 服务,可先行参考 Nacos 快速入门。 快速上手 Dubbo 融合 Nac…

在.NET Core中处理一个接口多个不同实现的依赖注入问题

前言近段时间在准备公司的技术分享,所以这段时间将大部分时间放在准备分享内容上去了。博客也就停了一下下。在.NET Core中处理依赖注入问题时,往往是定义好了一个操作规范的接口,会有N多个基于不同技术的实现,根据实际情况在项目…

Nacos(十)之Kubernetes Nacos

转载自 Kubernetes Nacos 本项目包含一个可构建的Nacos Docker Image,旨在利用StatefulSets在Kubernetes上部署Nacos 快速开始 Clone 项目 git clone https://github.com/nacos-group/nacos-k8s.git简单例子如果你使用简单方式快速启动,请注意这是没有使用持久化…

.net core连接MongoDB

前两天在学习MongoDB相关的知识,做了个小Demo,做的是省份下面有多少所学校,嗯,做的比较粗暴。。。连接MongoDB首先要通过Nuget添加一个MongoDB的包,下载此包安装完毕后开始写代码了,创建一个省份实体&#…

Nacos(十一)之NacosSync 介绍

转载自 NacosSync 介绍 介绍 NacosSync是一个支持多种注册中心的同步组件,基于Spring boot开发框架,数据层采用Spring Data JPA,遵循了标准的JPA访问规范,支持多种数据源存储,默认使用Hibernate实现,更加方便的支持表的自动创建更新使用了高效的事件异步驱动模型, 支持多种自…

Ocelot 集成Butterfly 实现分布式跟踪

微服务,通常都是用复杂的、大规模分布式集群来实现的。微服务构建在不同的软件模块上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此&#xff0…

聊聊AspectCore动态代理中的拦截器(一)

前言在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,由于介绍的比较浅显,也有不少同学留言询问拦截器的配置,那么在这篇文章中,我们来详细看一下AspectCore中的拦截器使用。两种配…

你可能不知道的.Net Core Configuration

执行原理1. 配置读取顺序:与代码先后顺序一致。public Startup(IHostingEnvironment env){var builder new ConfigurationBuilder().SetBasePath(env.ContentRootPath).AddJsonFile("appsettings.json", false, true).AddJsonFile("cussettings.jso…

Dubbo(一)之简介

转载自 Dubbo 2.7入门 一、背景 本文介绍了网站应用的演进 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。 单一…

Dubbo(二)之SpringBoot nacos集成

一、框架 使用springboot启动&#xff0c;注册中心现在naocs。 nacos安装 二、样例项目 &#xff08;1&#xff09;maven设置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId> <…

ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

在上文中&#xff0c;我们讨论了事件处理器中对象生命周期的问题&#xff0c;在进入新的讨论之前&#xff0c;首先让我们总结一下&#xff0c;我们已经实现了哪些内容。下面的类图描述了我们已经实现的组件及其之间的关系&#xff0c;貌似系统已经变得越来越复杂了。其中绿色的…

浅谈开发模式及架构发展

一、传统开发模式传统的开发模式基本一般是重服务端的开发方式&#xff0c;大部分工作都在服务端执行&#xff0c;然后返回到客户端&#xff08;通常是HTML&#xff09;。以Asp.net MVC为例&#xff0c;如下图&#xff1a;#1 根据请求的路由定位到对应的Controller的对应的Acti…