马哥 Linux SRE + AIOps智能运维文档
第 37 章 / 42

DevOps 之 GitLab 的CI

关于本文档 · 贡献者 · 文档协议 · 致谢

关于本文档

文档名称:《DevOps 之 GitLab 的CI》

使用协议:《知识共享公共许可协议(CCPL)》

贡献者

贡献者名称 贡献
度
文档变更记录 个人主页
马哥(马永亮) 主编 http://github.com/iKubernet
es/
王晓春 作者 53页,版本迭代升级,修订和内容丰富 http://www.wangxiaochun.c
om

文档协议

署名要求 :使用本系列文档,您必须保留本页中的文档来源信息,具体请参考《知识共享 (Creative Commons) 署名4.0公共许可协议国际版》。

非商业化使用 :遵循《知识共享公共许可协议(CCPL)》,并且您不能将本文档用于马哥教育相关业务之外的其他任何商业用途。

您的权利 :遵循本协议后,在马哥教育相关业务之外的领域,您将有以下使用权限:

共享 — 允许以非商业性质复制本作品。

改编 — 在原基础上修改、转换或以本作品为基础进行重新编辑并用于个人非商业使用。

致谢

本文档中,部分素材参考了相关项目的文档,以及通过搜索引擎获得的内容,这里先一并向相关的贡献者表示感谢。

← 上一章:企业级日志分析系统 ELK | 返回总目录 | 下一章:DevOps 之 Jenkins 的 CICD →


内容概述

DevOps 介绍

Git 版本管理系统

GitLab 私有仓库

1 DevOps 简介

1.1 传统开发模型

1.1.1 软件开发生命周期

软件开发生命周期SDLC (Software Development Life Cycle)由计划,分析,设计,实现,测试集成和维护组成

阶段1: 计划和需求分析 (Planning and Requirement Analysis)

每个软件开发生命周期模型都从分析开始,过程的利益相关者讨论对最终产品的要求。此阶段的目标是系统要求的详细定义。此外,还需要确保所有流程参与者都清楚地了解任务以及每个需求将如何实施。通常,讨论涉及质量保证专家,如果有必要,他们甚至可以在开发阶段干预过程中的添加。

阶段2: 设计项目架构 (Project Architecture)

在软件开发生命周期的第二阶段,开发人员实际上正在设计架构。所有利益相关者(包括客户)都会讨论此阶段可能出现的所有不同技术问题。此外,还定义了项目中使用的技术,团队负载,限制,时间范围和预算。最合适的项目决策是根据定义的要求做出的。

阶段3: 开发和编程 (Development and Coding)

在批准要求后,该过程进入下一阶段 - 实际开发。程序员从这里开始编写源代码,同时牢记先前定义的需求。系统管理员调整软件环境,前端程序员开发程序的用户界面以及与服务器交互的逻辑。 编程本身一般会用四个阶段:算法开发,源代码编写,编译,测试和调试

阶段4: 测试 (Testing)

测试阶段包括调试过程。开发过程中遗漏的所有代码缺陷都会在此处检测到,记录下来并传回给开发人员进行修复。重复测试过程,直到删除所有关键问题并且软件工作流程稳定。

阶段5: 部署 (Deployment)

当程序最终确定并且没有关键问题时 - 是时候为最终用户启动它了。新程序版本发布后,技术支持团队加入。该部门提供用户反馈; 在利用期间咨询和支持用户。此外,此阶段还包括所选组件的更新,以确保软件是最新的,并且不会受到安全漏洞的影响。

SDLC模型 (Software Development Life cycle Model)

从第一个也是最古老的“瀑布式”SDLC模型演变而来,其种类不断扩大。比较常见的SDLC模型如下

  • 瀑布模型 (Waterfall Model)

  • 迭代模型 (Iterative Model)

  • 螺旋模型 (Spiral Model)

  • V形模型 (V-Shape Model): 单元测试,集成测试,系统测试,验收测试

  • 敏捷模型 (Agile Model)

1.1.2 瀑布模型

瀑布模型是早期实现的开发模型,是一个级联SDLC模型,其中开发过程看起来像制造业的流水线,一步一步地进行分析,预测,实现,测试,实施和支持阶段。该SDLC模型包括完全逐步执行每个阶段。该过程严格记录并预定义,具有该软件开发生命周期模型的每个阶段所期望的功能。

优点 缺点
简单易用和理解 各个阶段的划分完全固定,阶段之间产生大量的文档,极大地增加了工作量
当前一阶段完成后,只需要去关注后续阶段 由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发风险
为项目提供了按阶段划分的检查节点 不适应用户需求的变化

1.1.3 敏捷开发

敏捷开发的核心是迭代开发(lterative Development)与增量开发(IncrementalDevelopment) 。

迭代开发:

对于大型软件项目,传统的开发方式是采用一个大周期(比如一年或数年)进行开发,整个过程就是一次"大开发"

迭代开发的方式则不一样,它将开发过程拆分成多个小周期,即一次"大开发"变成多次"小开发",每次小开发都是同样的流程,所以看上去就好像重复在做同样的步骤

比如: 某米公司生产手机,第一次生产某米1代(比较简陋),逐年再生产某米2代,目前已经到某米1X代

增量开发:

软件的每个版本,都会新增一个可以被用户感知到的完整功能。也就是说,按照新增功能来划分迭代。

比如: 房地产公司开发一个小区。如果采用增量开发的模式,该公司第一个迭代就是交付一期楼盘,第二个迭代交付二期楼盘..….每个迭代都是完成一栋完整的楼盘。而不是第一个迭代挖好所有楼的地基,第二个迭代建好每栋楼的骨架,第三个迭代架设屋顶.….....

虽然敏捷开发将软件开发分成多个迭代,但是也要求,每次迭代都是一个完整的软件开发周期,必须按照软件工程的方法论,进行正规的流程管理。

优势

尽早交付,加快资金回笼

  • 降级风险,及时了解市场需求

提高效率,阶段性功能折分及快速质量反馈

敏捷开发大幅提高了开发团队的工作效率,让版本的更新速度变得更快。

很多人可能会觉得,“更新版本的速度快了,风险不是更大了吗?”其实,事实并非如此。

敏捷开发可以帮助更快地发现问题,产品被更快地交付到用户手中,团队可以更快地得到用户的反馈, 从而进行更快地响应。而且,DevOps小步快跑的形式带来的版本变化是比较小的,风险会更小(如下图所示)。即使出现问题,修复起来也会相对容易一些。

1.2 DevOps 介绍

1.2.1 什么是 DevOps

DevOps 即开发 Development 和 Operations运维的缩写。

DevOps的维基百科定义是这样的:

DevOps是一组过程、方法与系统的统称,用于促进开发、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

DevOps 是针对开发人员、运维人员和测试人员的一种工作理念,是软件在应用开发、代码部署和质量测试等整条生命周期中协作和沟通的最佳实践

DevOps 强调整个组织的所有相关部门的紧密合作以及交付和基础设施变更的自动化、从而实现持续集成、持续部署和持续交付的目标

1.2.2 为什么要 DevOps

传统的模式是开发人员只关心开发程序,追求功能的变化和实现

运维只负责基础环境管理和代码部署及监控等,更看重应用的稳定运行

双方缺少一个共同的目标

DevOps 强调团队协作、相互协助、持续发展,实现团队作战,即无论是开发、运维还是测试,都为了最终的代码发布、持续部署和业务稳定而付出各自的努力,从而实现产品设计、开发、测试和部署的良性循环,实现产品的最终持续交付。

想要将DevOps真正落地,首先第一点,是思维转变,也就是“洗脑”。不仅是运维的要洗,开发的也要洗。员工要洗,领导更要洗。

DevOps并不仅仅是组织架构变革,更是企业文化和思想观念的变革。如果不能改变观念,即使将员工放在一起,也不会产生火花。

除了洗脑之外,就是根据DevOps思想重新梳理全流程的 规范和标准 。

在DevOps的流程下,运维人员会在项目开发期间就介入到开发过程中,了解开发人员使用的系统架构和技术路线,从而制定适当的运维方案。而开发人员也会在运维的初期参与到系统部署中,并提供系统部署的优化建议。

DevOps的实施,促进开发和运维人员的沟通,增进彼此的理(gan)解(qing)。

1.2.3 DevOps 相关的软件

在思维和流程改变的同时,想要充分落地DevOps,当然离不开软件和平台的支持。目前支持DevOps的软件很多了。

DevOps 涉及的四大相关平台

项目管理:如:Jira,禅道

代码托管:如:Gitlab,SVN 持续交付:如:Jenkins,Gitlab 运维平台:如:腾讯蓝鲸,Spug等

1.3 持续集成、持续交付和持续部署 CICD

最初是 瀑布模型 ,后来是 敏捷开发 ,现在是 DevOps ,这是现代开发人员构建出色的产品的技术路线。 随着DevOps的兴起,出现了 持续集成(Continuous Integration) 、 持续交付(Continuous Delivery) 、 持续部署(Continuous Deployment) 的新方法。传统的软件开发和交付方法正在迅速变得过时。从以前的敏捷时代,大多数公司会每月,每季度,每两年甚至每年发布部署/发布软件。然而现在在DevOps时代,每周,每天,甚至每天多次是常态。当SaaS正在占领世界时,尤其如此,您可以轻松地动态更新应用程序,而无需强迫客户下载新组件。很多时候,他们甚至都不会意识到正在发生变化。开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期,大多数团队都有自动化流程来检查代码并部署到新环境。

CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。CI/CD 的核心概念是持续集成、持续交付和持续部署。作为一个面向开发和运营团队的解决方案,CI/CD 主要针对在集成新代码时所引发的问题

具体而言,CI/CD 可让持续自动化和持续监控贯穿于应用的整个生命周期(从集成和测试阶段,到交付和部署)。这些关联的事务通常被统称为“CI/CD 管道”,由开发和运维团队以敏捷方式协同支持。

CICD 红帽参考连接

https://www.redhat.com/zh/topics/devops/what-is-ci-cd

https://docs.gitlab.com/ee/ci/introduction/

1.3.1 持续集成 (CI-Continuous Integration)

集成指将多位开发者的开发代码提交后,合并集成在一起,存放在代码库的过程,并且后续还会不断的迭代更新代码

持续集成是指多名开发者在开发不同功能代码的过程当中,可以频繁的将代码行合并到一起并切相互不影响工作。很多情况下每天都要进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。

CI属于开发人员的自动化流程。成功的 CI 意味着应用代码的新更改会定期构建、测试并合并到共享存储库中。该解决方案可以解决在一次开发中有太多应用分支,从而导致相互冲突的问题。

持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试 。

根据测试结果,可以确定新代码和原有代码能否正确地集成在一起。通过持续集成可以自动编译、打包、签名项目,配合单元测试可以实现持续集成+自动化测试。让工程师从重复而又枯燥的手动打包完全解放出来,让工程师能更加专注于代码本身,最大限度的减少误操作风险,降低修复错误代码的成本, 大幅提高工作效率。

1.3.2 持续交付(CD-Continuous Delivery)

完成 CI 中构建及单元测试和集成测试的自动化流程后,持续交付可以自动的将已验证的代码发布到存储库。为了实现高效的持续交付流程,务必要确保 CI 已内置于开发管道。 持续交付的目标是拥有一个可随时部署到生产环境的代码库。

在持续交付中,每个阶段(从代码更改的合并,到生产就绪型构建版本的交付)都涉及测试自动化和代码发布自动化。在流程结束时,运维团队可以快速、轻松地将应用部署到生产环境中。

持续交付完成了构建和测试过程细致的自动化,但是如何发布以及发布什么仍然是需要人工操作,持续部署可以改变这一点。

持续集成(CONTINUOUS INTEGRATION,CI)指的是开发人员频繁的(一天多次的)将所有开发者的工作合并到主干上。这些新提交在最终合并到主线之前,都需要通过编译和自动化测试流进行验证,以保障所有的提交在合并主干之后的质量问题,对可能出现的一些问题进行预警。持续集成的核心在于确保新增的代码能够与原先代码正确的集成。

持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的「类生产环境」 (production-like environments)中。比如,我们完成单元测试后,可以把代码部署到连接数据库的 Staging 环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境中。此方式是当前普遍采用的方式

1.3.3 持续部署(CD-Continuous Deployment)

对于一个成熟的 CI/CD 管道来说,最后的阶段是持续部署。作为持续交付(自动将生产就绪型构建版本发布到代码存储库)的进一步延伸, 持续部署可以自动将应用发布到生产环境。 由于在生产之前的管道阶段没有手动风控,因此持续部署在很大程度上都得依赖精心设计的测试自动化。

实际上,持续部署意味着开发人员对应用的更改在编写后的几分钟内就能生效(假设它通过了自动化测试)。这更加便于持续接收和整合用户反馈。总而言之,所有这些 CI/CD 的关联步骤都有助于降低应用的部署风险,因此更便于以小件的方式(而非一次性)发布对应用的更改。不过,由于还需要编写自动化测试以适应 CI/CD 管道中的各种测试和发布阶段,因此前期投资还是会很大。

持续部署是基于某种工具或平台实现代码自动化的构建、测试和部署到线上环境以实现交付高质量的产品,持续部署在某种程度上代表了一个开发团队的更新迭代速率。

与持续集成相比,持续交付(CONTINUOUS DELIVERY,CD)的侧重点在于交付,其核心对象不在于代码,而在于可交付的产物。由于持续集成仅仅针对于新旧代码的集成过程执行了一定的测试,其变动到持续交付后还需要一些额外的流程。与持续集成相比较,持续交付添加了测试Test->模拟Staging->生产 Production的流程,也就是为新增的代码添加了一个保证:确保新增的代码在生产环境中是可用的。

在持续交付的基础上,把部署到生产环境的过程自动化。如果你对比上图持续部署就可以发现持续部署和持续交付的区别就是最终部署到生产环境是自动化的。因为自动发布存在较大的风险,当前采用此方式较少.

1.4 CICD 流程过程和架构

1.4.1 应用部署发展阶段

  • 开发人员自行上传代码

  • 早期项目,没有专业的运维人员,运维的工作由开发兼职完成,项目发布很不专业,很容易出错,也是最原始的方式

  • 开发人员先将代码发给运维,再由运维人员手动上传至生产环境

  • 专业的运维人员完成应用的部署,每次项目发布都由运维人员一步一步手动实现,效率低下且容易出错

  • 运维利用脚本和自动化运维工具实现部署

  • 由运维人员编写Shell,Python等脚本或利用自动化运维工具,如Ansible等实现半自动化应用部署,效率很高,但对技术的专业性有较高要求

  • 通过 Web 等 GUI 界面实现一键自动化部署

  • 可以通过开源或自研的运维平台实现方便的应用部署,操作容易,效率高,但需要提前构建运维平台

1.4.2 CICD 相关工具

1.4.3 CICD 流程

开发人员不断的进行代码提交到本地,再提交到运程的代码仓库服务器

Jenkins作为持续集成工具,使用Git工具到Git仓库拉取代码到集成服务器,代码测试与审查,再配合JDK,Maven,Go等软件完成代码编译,测试,打包等工作,在这个过程中每一步如果出错,都

需要重新再执行一次整个流程。

  • Jenkins把生成的软件jar或war包等分发到测试服务器或者生产服务器,测试人员或用户就可以访问应用。

1.4.4 Kubernetes 环境的 CICD

1.4.5 CICD 服务器架构

1.5 版本控制系统 VCS

版本控制系统(Version Control System,VCS)是一种软件,可以帮助软件团队的开发人员协同工作,并存档他们工作的完整历史记录。

为什么使用 VCS ?

在实际开发过程中,经常会有这种需求或问题

  • 代码可能被破坏,比如误删除等,希望还能找回

  • 代码出现了严重的Bug,希望回滚至数周前的旧代码

  • 需要在已经发布的程序中添加新的功能,如果测试验证后没有问题,才会使用新的代码,而在测试验证期间,不能影响原来的代码

  • 同一个软件需要有多个版本并行开发,满足不同的应用需求

  • 实际项目开发基本都是多个人合作完成,在多个人写代码时,就牵扯到代码合并成一份的问题。

1.5.1 版本控制系统分类

本地版本控制系统

  • 第一代版本控制系统被称为本地版本控制系统。通过加锁将并发执行转换成顺序执行。 一次只能有一个人处理文件。

具体流程如下:首先,应该把文件放在一个服务器上,方便使用者上传或下载文件;其次,任何人想对文件修改时,需要先把这个文件加锁,通过checkout指令,使得其他人无法修改;最后,当修改完成之后,需要释放锁,通过checkin指令,形成一个新的版本,存放到服务器端。

第一代版本控制系统主要有 RCS、SCCS(1972年发布)和 DSEE(被认为是 Atria ClearCase 的前身)。目前,有些项目还在使用!

悲观锁
每次获取数据的时候,都会担心数据被修改,所以每次获取数据的时候都会进行加锁,确保在自己使用的
过程中数据不会被别人修改,使用完成后进行数据解锁。由于数据进行加锁,期间对该数据进行读写的其
他线程都会进行等待。
乐观锁
每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数
据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没
有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操
作。
乐观锁一般会使用版本号机制或 CAS 算法实现。

集中式版本控制系统

用户想要完成任何的提交和回滚都依赖于连接集中的代码服务器才能实现,比如下班回家后,如果无法连接至代码的服务器,将无法提交代码

此外此服务器还存在单点问题

分布式版本控制系统

在每个用户都有一个完整的服务器,然后再部署一个中央服务器

用户可以先将代码提交到本地,没有网络也可以先提交到本地,然后在有网络的时候再提交到中央服务器,这样就大大方便了开发者

相比集中式的版本控制系统,工作的时候需要先从中央服务器获取最新的代码,改完之后需要提交,如果是一个比较大的文件则需要足够快的网络才能快速提交完成,而使用分布式的版本控制系统,每个用户都是一个完整的版本库,即使没有中央服务器也可以提交代码或者回滚,最终再把改好的代码提交至中央服务器进行合并即可。

1.5.2 常见的版本控制系统

1.5.2.1 CVS(Concurrent Version System) 集中式版本控制系统

并发版本系统(Concurrent Versions System,CVS)是最初的第二代版本控制系统。大约十年间,它是最为流行的版本控制系统,直到 2000 年被 Subversion 所取代。

CVS 最早是由一位名叫 Dick Grune 的荷兰科学家于 1986 年 6 月 23 日公开发布了该代码。CVS 最初仅仅只是一个包装了 RCS( 修订控制系统(Revision Control System)) 的 Shell 脚本集合。最终演变成当前版本的 CVS 的代码始于 1989 年 4 月的 Brian Berliner 的贡献,后来由 Jeff Polk 和许多其他贡献者提供帮助。 Brian Berliner 撰写了一篇论文,介绍了他对 CVS 程序的改进 - 该程序描述了该工具是如何在 Prysma 内部扩展和使用的。 1990 年 11 月 19 日,CVS 1.0 版被提交给自由软件基金会进行开发和分发。

CVS是一个C/S系统,是一个早期常用的代码版本控制软件。多个开发人员通过一个中心版本控制系统来记录文件版本,从而达到保证文件同步的目的。CVS版本控制系统是一种GNU软件包,主要用于在多人开发环境下的源码的维护。

由于 CVS 是集中式版本控制系统,所以它有客户端和服务端之区分。但要开始使用 CVS 的话,即使只在你的本地机器上使用,也必须设置 CVS 的服务端。

1.5.2.2 SVN(Subversion) 集中式版本控制系统

SVN 由 CollabNet 公司于 2000 年资助并发起开发,目的是创建一个更好用的版本控制系统以取代 CVS。

2000 年 2 月,CollabNet 联系了 Open Source Development with CVS(Coriolis, 1999)的作者 Karl Fogel,问他是否愿意为这个新项目工作。这时 Karl 已经在和他的朋友 Jim Blandy 讨论一个新的版本控制系统的设计。他不仅已经起好了名字 “Subversion”,而且有了 Subvesion 资料库的基本设计。

经过 14 个月的编码,在 2001 年 8 月 31 号,Subversion 可以“自我寄生”了。就是说,Subversion 开发人员停止使用 CVS 管理 Subversion 的源代码,开始使用 Subversion 代替。

2009 年 11 月,Subversion 被 Apache Incubator 项目所接收。2010 年 1 月,正式成为 Apache 软件基金会的一个顶级项目

SVN 依赖于网络,需要在各个开发主机上安装客户端软件,并且在一台服务器集中进行版本管理和存储. 目前依然有部分公司在使用

优点:

管理方便,逻辑明确,符合一般人思维习惯。

  • 易于管理,集中式服务器更能保证安全性。

  • 代码一致性非常高。

  • 适合开发人数不多的项目开发。

缺点:

服务器压力太大,数据库容量暴增。

  • 如果不能连接到服务器上,基本上不可以工作,如果服务器不能连接上,就不能提交,还原,对比等等。

  • 不适合开源开发(开发人数非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题。

1.5.2.3 Git

在 Linux 开源的初期,Linux 开源项目的代码是 linus 本人通过 linux 命令 diff 和 patch 两条命令手动完成。随着 Linux 代码越来越壮大,靠 Linus 一个人来手动合并已经不现实。2002 年,Linus 选择了一个商业版本控制系统 BitKeeper 作为 Linux 内核的代码管理工具(BitKeeper 的开发商 BitMover 授权 linux 社区免费使用)。但是,免费使用是有很多的限制的,因此 linux 社区的大佬开始破解 BitKeeper。其中,samba 的作者 andrew 破解成功了。但是被 BitMover 公司发现,收回免费使用权。

迫不得已,Linus 选择了自己开发一个分布式版本控制工具以替代 BitKeeper。linus 闭关一个月,写出了 Git。在一个月后,Git 成功接管了 Linux 社区的版本控制工作,并且开始开源。维基百科中,有如下历史记录:

2005年4月3日,开始开发 Git。
2005年4月6日,项目发布。
2005年4月7日,Git就可以作为自身的版本控制工具了。
2005年4月18日,发生第一个多分支合并。
2005年4月29日,Git 的性能就已经达到了 Linus 的预期。
2005年6月16日,Linux 2.6.12 发布,那时 Git 已经在维护 Linux 核心的源代码了。
2005年7月26日,Linus 功成身退,将 Git 的维护交给另外一个 Git 的主要贡献者 Junio C
Hamano。
2016年5月,BitKeeper宣布使用 Apache 2.0许可证开源。

Git 重要特性:

在本地就可以完成提交,因此不需要网络,提交完成后,可以有网络环境时,再同步到远程仓库服务器

优点:

适合分布式开发,强调个体。

  • 公共服务器压力和数据量都不会太大。

  • 速度快、灵活。

任意两个开发者之间可以很容易的解决冲突。

  • 支持离线工作。

缺点:

不符合常规思维。

  • 学习周期相对而言比较长。

代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息。

1.5.2.4 Github 网站

2008年1月,Wanstrath和Preston-Werner推出使用Ruby on Rails编写而成的GitHub的个人测试版。2 月,他们又增加了第三位联合创始人PJ Hyett,到2008年3月,GitHub的beta版已经拥有了2000名用户。GitHub于2008年4月推出公共版本,然后逐渐在开发者社区中流行起来,到2009年7月,用户数量达到了10万。

由于GitHub在软件开发人员中很受欢迎,成立后的四年,GitHub通过向个人程序员和企业收取每月访问平台的费用,在没有外部资金的情况下得以生存下来。

GitHub网站为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby 等等。GitHub同时提供付费账户和免费账户。这两种账户都可以创建公开的代码仓库,但是只有付费账户可以创建私有的代码仓库。

2018年6月5日微软花费 75 亿美元收购 GitHub

2019年1月7日免费的 GitHub 用户现在可以获得不受限制的私人项目,最多可以有三个协同合作者

2020年4月14日 GitHub宣布向所有用户和团队提供不限制协作人数的私有仓库,同时GitHub的核心功能对所有人免费开放

官网: http://www.github.com

1.5.2.5 GitLab 网站和软件

Github 提供了公有云的软件仓库服务,但实现私有仓库早期是收费的,而GitLab的出现解决了这一问题。GitLab由乌克兰程序员DmitriyZaporozhets和ValerySizov开发,它使用Ruby语言写成。后来,一些部分用Go语言重写,是完全免费的开源软件,按照MIT许可证分发。2013年7月,GitLab产品被拆分为两个版本:GitLab CE(社区版)和GitLab EE(企业版),2014年2月,GitLab宣布采用开放核心业务模式。GitLabEE设置在专有许可证下,并且包含CE版本中不存在的功能。GitLabCE是使用MIT许可证的基于网络的Git仓库管理工具,且具有wiki和issue跟踪功能。使用Git作为代码管理工具,并在此基础上搭建起来的Web服务。

从安全方面来看,公司不希望员工获取到全部的代码,这个时候Gi tLab是最佳的选择。但对于开源项目而言,GitHub 依然是代码托管的首选平台。

GitLab 官方网站: https://about.gitlab.com/

Gitlab 企业版:

Gitlab 的优势

  • 开源免费,搭建简单、维护成本较低、可适用于中小型公司内部项目使用。 权限管理功能强大灵活,能实现代码对部分人可见,确保项目的安全性。 支持离线提交,基于git实现,可以不在实时依赖网络环境进行代码提交。

1.6 常见的软件部署模式

1.6.1 蓝绿部署 Blue-green Deployments

蓝绿部署指的是不停止老版本代码(不影响上一个版本访问),而是在另外一套环境部署新版本然后进行测试,测试通过后将用户流量切到新版本,其特点为业务无中断,升级风险相对较小。但本方式成本较高, 一般小公司较少使用

蓝绿色部署是一种部署策略,利用两种相同的环境,即"蓝色"(又名预发布)环境和"绿色"(又名生产) 环境,具有不同版本的应用程序或服务。质量保证和用户接受度测试通常在承载新版本或更改的蓝色环境中进行。一旦蓝色环境中测试并接受新的变化,用户流量就会从绿色环境转变为蓝色环境。然后,一旦部署成功,您可以切换到新环境。

具体过程:

  • 1、当前版本(V1)业务正常访问

  • 2、在另外一套环境部署新代码版本(V2),代码可能是增加了功能或者是修复了某些bug

  • 3、测试通过之后将用户请求流量切到新版本环境

  • 4、观察一段时间,如有异常直接切换旧版本

  • 5、下次升级,将旧版本(V2)升级到新版本(V3)

蓝绿部署适用的场景:

  • 1、不停止老版本,额外部署一套新版本,等测试确认新版本正常后,才将用户请求切换至新版本,如果有问题,切换回老版本

  • 2、蓝绿发布是一种用于升级与更新的发布策略,部署的最小维度是容器,而发布的最小维度是应用。

  • 3、蓝绿发布对于增量升级有比较好的支持,但是对于涉及数据表结构变更等等不可逆转的升级,并不完全合适用蓝绿发布来实现,需要结合一些业务的逻辑以及数据迁移与回滚的策略才可以完全满足需求。

1.6.2 金丝雀(灰度)发布 Canary Deployment

“金丝雀”的由来:17世纪英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;而当瓦斯含量超过一定限度时,虽然人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人每次下井都会带上一只金丝雀作为“瓦斯检测指标”,以便在危险状况下紧急撤离。

金丝雀发布也叫灰度发布,是指在黑与白之间,能够平滑过渡的一种发布方式,灰度发布是增量发布 (例如:2%、25%、75%、100%)进行更新)的一种类型,灰度发布是在原有版本可用的情况下,同时部署一个新版本应用作为“金丝雀”(小白鼠),测试新版本的性能和表现,以保障整体系统稳定的情况下, 尽早发现、调整问题。因此,灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

此方式在实际生产中使用较为普遍

金丝雀/灰度发布步骤组成:

  • 1、准备好部署各个阶段的工件,包括:构建组件,测试脚本,配置文件和部署清单文件。

  • 2、从负载均衡列表中移除掉“金丝雀”服务器(选择全部服务器中的一部分)。

  • 3、升级“金丝雀”应用(排掉原有流量并进行部署)。

  • 4、对应用进行自动化测试。

  • 5、将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)。

  • 6、如果“金丝雀”在线使用测试成功,升级剩余的其他服务器。否则就回滚回旧版本

金丝雀/灰度发布部署适用的场景:

  • 1、不停止老版本,额外搞一套新版本,不同版本应用共存。

  • 2、灰度发布中,常常按照用户设置路由权重,例如90%的用户维持使用老版本,10%的用户尝鲜新版本。

  • 3、经常与A/B测试一起使用,用于测试选择多种方案。

1.6.3 滚动发布(更新)

滚动发布故名思议,就是逐步升级服务中的节点

滚动发布是指每次只升级一个或多个服务实例,升级完成后加入生产环境,不断执行这个过程,直到集群中的全部旧版本升级新版本。

红色:正在更新的实例

蓝色:更新完成并加入集群的实例

绿色:正在运行的实例

滚动发布过程

  1. 先升级1个服务实例,主要做部署验证;

  2. 每次升级1个服务实例,自动从LB上摘掉,升级成功后自动加入集群

  3. 事先需要有自动更新策略,分为若干次,每次数量/百分比可配置

  4. 回滚是发布的逆过程,先从LB摘掉新版本,再升级老版本,这个过程一般时间比较长

  5. 自动化要求高

1.6.4 A/B测试 A/B Testing

A/B测试即同时对外提供两个APP运行环境,这和蓝绿部署的同时只有一个版本在线是不同的

A/B 测试是用来测试应用功能表现的方法,例如可用性、受欢迎程度、可见性等等

蓝绿部署和A/B测试是不同的,蓝绿部署的目的是安全稳定地发布新版本应用,并在必要时回滚,即蓝绿部署是同一时间只有一套正式环境在线,而A/B测试是两套正式环境同时在线,一般用于多个产品竟争时使用

2 版本控制系统 Git

2.1 数据保存方式

https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-
%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F

SVN 与 CVS:

每次提交的文件都单独保存, 即按照文件的提交时间区分不同的版本, 保存至不同的逻辑存储区域,后期恢复时候直接基于之前版本恢复。 将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异 (它们通常称作基于差异(delta-based) 的版本控制)

Git:

在 Git中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个快照流。

git和SVN区别

  • git是分布式的,svn是集中式的

  • git是每个历史版本都存储完整的文件,便于恢复,svn是存储差异文件

  • git可离线完成大部分操作,svn则不能

  • git有着更优雅的分支和合并实现

  • git有着更强的撤销修改和修改历史版本的能力

  • git速度更快,效率更高

2.2 Git 相关概念和原理

2.2.1 Git 的区域

  • 工作区 workspace:clone的代码或者开发编写代码文件所在的目录 ,通常是一个服务代码所在的目录名称 ,对应于<项目目录>

  • 暂存区index :用于存储在工作区中对代码进行修改后的文件所保存的地方,只有放入此区的文件才能被git进行管理,使用 git add添加,对应为<项目目录>/.git/index文件

  • 本地仓库repo: 用于存储在工作区和暂存区中改过并提交的文件地方,使用 git commit 提交,对应于/<项目目录>/.git/

  • 远程仓库 :多个开发人员共同协作提交代码的仓库,即私有 gitlab 服务器或公有云github,gitee网站等

2.2.2 文件的状态变化周期

untracked: 在工作目录下创建的新文件,这个时候本地git仓库不知道,不能对其进行版本跟踪管理 unmodified: 添加到暂存区的文件未修改,把文件从暂存区推动到本地仓库

modified: 已经添加到暂存区的文件,在本地工作区的文件被修改了 ,需要重新添加至暂存区

staged: 文件添加到了本地仓库里面的暂存区

2.2.3 Git 分支和标签

分支: 对文件的副本,可以实现多个不同用途的软件版本同时的演进,实现多个开发版本的隔离

分支在实际中有什么用呢?

假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交, 由于代码还没写完,不完整的代码库会导致别人不能测试等工作。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

现在有了分支,就不用担心了。你创建了一个独立的分支,对其他人是透明的,没有影响,他们还继续在原来的分支上正常工作,而你在自己的分支上工作,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样既安全,又不影响别人工作。

tag: 给某个状态打个标签用于记录当前状态,相当于里程碑

tag是git版本库的一个标记,指向某个commit的指针。

tag主要用于发布版本的管理,一个版本发布之后,可以为git打上 v1.0.1,v1.0.2 ...这样的类似的标签。

tag跟branch有点相似,但是本质上和分工上是不同的:

tag 对应某次commit, 是一个点,是不可移动的。

branch 对应一系列commit,是很多点连成的一根线,有一个HEAD 指针,是可以依靠 HEAD 指针移动的。

所以,两者的区别决定了使用方式,改动代码用 branch ,不改动只查看用 tag。

tag 和 branch 的相互配合使用,有时候起到非常方便的效果

例如:已经发布了 v1.0 v2.0 v3.0 三个版本,这个时候,我突然想不改现有代码的前提下,在 v2.0 的基础上加个新功能,作为 v4.0 发布。就可以检出 v2.0 的代码作为一个 branch ,然后作为开发分支。

2.2.4 开发分支流程

2.3 Git 安装

2.3.1 Linux 安装 git

https://git-scm.com/download/linux

2.3.1.1 二进制包安装

CentOS和Ubuntu 系统源都带有git版本,可以直接安装

范例: Rocky安装git

[root@rocky8 ~]#yum -y install git
[root@rocky8 ~]#git version
git version 2.27.0

范例: Ubuntu 安装 git

[root@ubuntu2004 ~]#apt update
[root@ubuntu2004 ~]#apt -y install git
[root@ubuntu2004 ~]#git version
git version 2.25.1
[root@ubuntu1804 ~]#apt update
[root@ubuntu1804 ~]#apt -y install git
[root@ubuntu1804 ~]#git version
git version 2.17.1

范例: Ubuntu 安装最新版

[root@ubuntu1804 ~]#apt list  git
Listing... Done
git/bionic-security,bionic-updates 1:2.17.1-1ubuntu0.9 amd64 [upgradable from:
1:2.17.1-1ubuntu0.7]
[root@ubuntu1804 ~]#add-apt-repository ppa:git-core/ppa
[root@ubuntu1804 ~]#apt update
[root@ubuntu1804 ~]#apt list git
Listing... Done
git/bionic 1:2.33.0-0ppa1~ubuntu18.04.1 amd64 [upgradable from: 1:2.17.1-
1ubuntu0.7]
N: There are 3 additional versions. Please use the '-a' switch to see them.
[root@ubuntu1804 ~]#apt -y install  git
[root@ubuntu1804 ~]#git version
git version 2.33.0
2.3.1.2 源码安装

源码下载

https://www.kernel.org/pub/software/scm/git
https://github.com/git/git/releases

范例: Rocky 8 编译安装git

[root@rocky8 ~]#yum -y install gcc make  openssl-devel curl-devel expat-devel
[root@rocky8 ~]#wget -P /usr/local/src
https://github.com/git/git/archive/refs/tags/v2.33.0.tar.gz
[root@rocky8 ~]#wget -P /usr/local/src
https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.33.0.tar.gz
[root@rocky8 ~]#cd /usr/local/src
[root@rocky8 src]#tar xf v2.33.0.tar.gz
[root@rocky8 git-2.33.0]#cd git-2.33.0/
#如果用旧版git,可以执行下面操作
[root@rocky8 ~]#git clone https://gitee.com/lbtooth/git.git
[root@rocky8 ~]#cd git/
[root@rocky8 git-2.33.0]#cat INSTALL
[root@rocky8 git-2.33.0]#make -j `grep -c processor /proc/cpuinfo`
prefix=/apps/git all
[root@rocky8 git-2.33.0]#make prefix=/apps/git install
[root@rocky8 git-2.33.0]#echo 'PATH=/apps/git/bin/:$PATH' >
/etc/profile.d/git.sh
[root@rocky8 git-2.33.0]#. /etc/profile.d/git.sh
[root@rocky8 git-2.33.0]#git version
git version 2.33.0

2.3.2 Windows 安装 git

https://git-scm.com/downloads

注意:

Windows 版本的 git 在提交前,必须配置邮箱和用户名

git clone 时提交的用户密码信息会记录在凭据管理器中Windows凭据的普通凭据中,即修改密码后,需要删除凭据中密码

2.3.3 Mac 安装 git

https://git-scm.com/download/mac

2.4 Git 常用语法

使用 git 命令添加代码,提交等管理代码操作

2.4.1 Git 用法说明

官方文档:

https://git-scm.com/docs
https://git-scm.com/book/zh/v2

区域间文件操作

git 命令常见用法

git help <子命令> #不加<子命令>是查看git命令的帮助
git <子命令> --help#不加<子命令>是查看git命令的帮助
git version  #查看版本
git init       #本地仓库初始化
git init --bare#创建无工作区的祼仓库,适用于充当远程仓库,一般对应的目录以.git为后缀
git clone http://url         #克隆url指定的项目的所有文件,并在本地创建此项目的git仓库
git clone -b develop http://url  #克隆url指定的项目中develop分支
git clone -b tag http://url  #克隆url指定的项目中tag
git config --global user.name "wangxiaochun"#设置当前用户的git全局用户名,和下面两项都
存放在~/.gitconfig文件中
git config --global user.email "29308620@qq.com"#设置全局邮箱
git config --global color.ui true#让Git显示颜色,会让命令输出看起来更醒目
git config --global core.editor vim#git默认的编辑器为nano,不常用,需要修改为vim
git config --global--list|-l  #列出用户全局设置,默认保存在~/.gitconfig文件中
git config --global-e#交互编辑配置
git add index.html / . #添加指定文件、目录或当前目录下所有数据到暂存区
gitrm--cached file   #只删除暂存区的文件,不删除工作区文件,相当于git add 反操作
gitrm  file           #从删除工作目录和暂存区删除文件
git checkout file      #从暂存区复制文件到工作目录
git restore file       #新版EXPERIMENTAL命令,可以恢复修改的工作区文件
git ls-files           #查看暂存区文件,选项-s显示mode bits, object name and stage
number,-o显示untracked文件
git cat-file -p <blogid>  #查看仓库对象的内容,仓库对象存放在.git/objects目录下
gitdiff  [file]     #对比工作区和暂存区的区别
gitdiff--cached file     #对比暂存区和本地仓库的区别
gitdiff <commit> -- <path> #对比工作区和指定提交的区别
gitdiff <commit> <commit> -- <path> #提交和提交之间的区别
git commit -m  “comment“ #提交文件到工作区
git commit -am"comment"#添加所有修改(不包括新文件)到暂存区并提交,相当于git add + git
commit
git commit --amend--no-edit#重新覆盖上次的提交
git commit --amend-m"comment"#重新提交,覆盖上次的提交
git status #查看工作区的状态
git log -p#查看每次提交的变化
git log  --pretty=oneline
git log --oneline-1#查看最近一条commit日志
git log origin/main  #查看远程仓库的日志
git reflog  #查看分支或其它引用在本地仓库的完整历史记录
git reset --hard HEAD^^ #git版本回滚, HEAD为当前版本,加一个^为上一个,^^为上上一个版本
git reset --hard HEAD~n #回滚前n个版本
git reset --hard 5ae4b06 #回退到指定id的版本,使用 git reflog 获取每次提交的ID
git reset --hard v1.0
git branch #查看分支及当前所处的分支
git branch -av#查看所有本地和远程分支
git branch <分支名> #创建分支<分支名>
git branch <分支名> <commit_id> #基于指定提交创建新分支
git branch -d <分支名>  #删除分支
git branch -m dev develop #修改分支名dev为develop
git branch -M main #修改当前分支名称为main
git checkout <分支名>  #切换到已有的分支
git checkout v1.0 #切换至指定标签v1.0
git checkout -b <分支名> #创建并切换到一个新分支
git checkout -b <分支名> origin/<分支名> #利用服务器远程仓库的分支,同步在本地创建分支
git checkout [<commit>]-- <file> ...  #找回在工作区删除的已存入暂存区或提交的文件
git merge master -m"mastertodev"#将master分支合并至当前分支,无选项-m, 则为交互式
git tag v1.0 #当前状态创建标签
git tag -a v1.0 b720aaf -m"v1.0"#将指定commit创建标签
git tag -d v1.0    #删除标签
git reset --hard v1.0       #回滚到指定标签
git tag #查看标签
git show v1.0 #查看标签
git remote -v#查看远程仓库
git remote show origin #查看远程仓库详细信息
git remote add origin git@gitlab.example.com:testgroup/testproject.git #建立远程仓
库和本地origin关联
git remote rename origin old-origin  #修改名称
git remote remove origin #删除关联
git push #将本地仓库提交代码到远程服务器
git push origin master #将当前分支推送到远程的 master 分支
git push origin dev    #将当前分支推送到远程的dev分支,如果远程没有dev会自动创建
git push -u origin master #将本地 master 分支推送到远程仓库 master,并且参数-u表示以后即
可直接用git push 代替此命令
git push origin main:dev #将本地main分支推送至远程dev分支
git push origin :dev #将空分支推送到远程dev,即删除远程dev分支
git push origin v1.0 #将本地仓库v1.0的tag推送到远程
git push -u origin --all#推送所有分支
git push origin --tags#将本地仓库所有的tag都推送到远程
git push origin --tag v1.0 #只推送指定的tag到远程
git pull #从远程服务器获取代码到本地仓库,并合并到本地仓库
git pull origin dev #从远程服务器分支dev拉取代码到本地仓库
git fetch #从远程仓库获取最新版本,不合并至本地仓库
vim .gitignore #定义忽略文件,即不放在仓库的文件

git log 显示日志格式

git log --graph --pretty=format:'参数'

参数说明

参数 说明
%H commit hash
%h commit short hash
%T tree hash
%t tree short hash
%P parent hash
%p parent short hash
%an 作者名字
%aN .mailmap中对应的作者名字
%ae 作者邮箱
%aE .mailmap中对应的作者邮箱
%ad –date=制定的日期格式
%aD RFC2822日期格式
%ar 日期格式,例如:1 day ago
%at UNIX timestamp日期格式
%ai ISO 8601日期格式
%cn 提交者名字
%cN .mailmap对应的提交的名字
%ce 提交者邮箱
%cE .mailmap对应的提交者的邮箱
%cd –data=制定的提交日期的格式
%cD RFC2822提交日期的格式
%cr 提交日期的格式,例如:1day ago
%ct UNIX timestamp提交日期的格式
%ci ISO 8601提交日期的格式
%d ref名称
%e encoding
%s commit信息标题
%f 过滤commit信息的标题使之可以作为文件名
%b commit信息内容
%N commit notes
参数 说明
%gD reflog selector, e.g., refs/stash@{1}
%gd shortened reflog selector, e.g., stash@{1}
%gs reflog subject
%Cred 切换至红色
%Cgreen 切换至绿色
%Cblue 切换至蓝色
%Creset 重设颜色
%C(color) 制定颜色,as described in color.branch.* config option
%m left right or boundary mark
%n 换行
%% a raw %
%x00 print a byte from a hex code
%w([[,[,]]]) switch line wrapping, like the -w option of git-shortlog(1).

2.4.2 案例

2.4.2.1 创建项目并初始化配置
[root@gitlab ~]#mkdir /data/testproject/
[root@gitlab ~]#cd /data/testproject/
[root@gitlab testproject]#git init
[root@gitlab testproject]#ls -a
.  ..   .git
[root@gitlab testproject]#tree .git
.git
├── branches                #分支
├── config                  #git config命令设置的配置信息
├── description             #被git web(Github的原型)用来显示对仓库的描述
├── HEAD                    #当前分支的标识符号,一般指向refs/heads目录下的分支文件
├── hooks                   #触发器规则的文件,俗称"钩子文件"
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
├── info                    #一些特殊文件设置目录,比如忽略文件设置,.gitignore是互补的
│   └── exclude
├── objects                 #存放git对象,git 核心的文件目录
│   ├── info
│   └── pack
└── refs                    #各个提交对象的标识(SHA-1)文件
    ├── heads               #分支相关信息的目录
    └── tags                #标签相关信息的目录
9 directories, 17 files
#设置git
#选项--system 表示针对所有用户的配置,保存在/etc/gitconfig文件中
#选项--global 表示当前用户环境,保存在~/.gitconfig文件中,推荐使用
#选项--local  表示只针对当前目录(项目)的配置,保存在当前目录的.git/config文件中,此为默认值,
可省略
#优先级:local > global > system
[root@gitlab ~]#git config --global user.name wangxiaochun
[root@gitlab ~]#git config --global user.email root@wangxiaochun.com
[root@gitlab ~]#git config --global color.ui true
[root@gitlab ~]#git config --global core.editor vim
[root@gitlab ~]#git config  --system user.name wang
#查看system,global和local的配置
[root@gitlab ~]#git config -l
user.name=wangxiaochun
user.email=root@wangxiaochun.com
core.editor=vim
[root@gitlab ~]#cat .gitconfig
[user]
    name = wangxiaochun
    email =29308620@qq.com
#只查看global配置
[root@gitlab ~]#git config -l --global
#交互编辑配置
[root@gitlab ~]#git config --global -e
#删除配置
[root@gitlab ~]#git config --unset --system user.name
2.4.2.2 添加暂存区并提交数据
[root@gitlab testproject]#touch a.txt
[root@gitlab testproject]#git add a.txt
[root@gitlab testproject]#git commit -m 'add a.txt'

注意:

如果工作区和暂存区数据不一致,会显示红色的提示

如果暂存区和本地仓库数据不一致,会显示绿色的提示

2.4.2.3 设置忽略文件

配置.gitignore文件让 Git 不再管理当前目录下的某些文件。

生产中有如下几类文件可能需要忽略

  • 程序运行时产生的临时文件

  • 程序连接数据库这一类的配置文件

程序本地开发使用的图片文件

  • 其它不想被共享的文件

范例: 忽略指定文件

[root@gitlab testproject]#cat .gitignore
/bin
/target
.classpath
.project
.settings
*.h
!test.h
*.py[c|x]
#注意:需要提交后才能生效忽略
[root@gitlab testproject]#git add .
[root@gitlab testproject]#git commit -m '设置忽略'
2.4.2.4 将文件加入暂存区再取消添加
[root@gitlab testproject]#touch f1.txt
[root@gitlab testproject]#git status
On branch master
No commits yet
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    f1.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@gitlab testproject]#git add f1.txt
#查看暂存区文件
[root@gitlab testproject]#git ls-files
f1.txt
[root@gitlab testproject]#git status
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
    new file:   f1.txt
#从暂存区删除
#方法1
[root@gitlab testproject]#git rm --cached f1.txt
#方法2
[root@gitlab testproject]#git restore --staged f1.txt
#确认是否从暂存区删除
[root@gitlab testproject]#git status
On branch master
No commits yet
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    f1.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@gitlab testproject]#git ls-files
[root@gitlab testproject]#
2.4.2.5 查看暂存区的文件内容
[root@rocky8 testproject]#echo test.txt > test.txt
[root@rocky8 testproject]#git add .
[root@rocky8 testproject]#git ls-files -s
100644 4871fd52755be519c29ae719f385bd5f2863627c 0   test.txt
[root@rocky8 testproject]#file
.git/objects/48/71fd52755be519c29ae719f385bd5f2863627c
.git/objects/48/71fd52755be519c29ae719f385bd5f2863627c: VAX COFF executable -
version 20741
[root@rocky8 testproject]#git cat-file -t
4871fd52755be519c29ae719f385bd5f2863627
blob
[root@rocky8 testproject]#git cat-file -p
4871fd52755be519c29ae719f385bd5f2863627c
test.txt
2.4.2.6 利用暂存区恢复误删除的工作区文件
[root@gitlab testproject]#touch test.txt
[root@gitlab testproject]#git add .
[root@gitlab testproject]#git ls-files
README.md
b.txt
test.txt
[root@gitlab testproject]#rm -f test.txt
[root@gitlab testproject]#ls
README.md
#从暂存区复制文件到工作目录
[root@gitlab testproject]#git checkout test.txt
[root@gitlab testproject]#ls
README.md  test.txt
2.4.2.7 同时删除工作区和暂存区
[root@gitlab testproject]#touch f2.txt
[root@gitlab testproject]#git add .
[root@gitlab testproject]#git ls-files
f1.txt
f2.txt
[root@gitlab testproject]#ls
f1.txt  f2.txt
#同时删除工作区和暂存区文件
[root@gitlab testproject]#git rm -f f2.txt
rm'f2.txt'
[root@gitlab testproject]#ls
f1.txt
[root@gitlab testproject]#git ls-files
f1.txt
2.4.2.8 回滚工作区的文件为暂存区中版本
[root@gitlab testproject]#echo v1 > f1.txt
[root@gitlab testproject]#git status
On branch master
No commits yet
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    f1.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@gitlab testproject]#git add .
[root@gitlab testproject]#echo v2 > f1.txt
[root@gitlab testproject]#git status
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
    new file:   f1.txt
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
    modified:   f1.txt
#回滚工作区的文件为暂存区中版本
[root@gitlab testproject]#git checkout -- f1.txt
[root@gitlab testproject]#cat f1.txt
v1
2.4.2.9 多次提交后回滚至指定提交的版本

2.4.2.9.1 git reset

git reset 官方说明

https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-
%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86
https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified

git reset 是对本地仓库的项目进行回滚操作的命令,它主要有如下三个参数

--soft  工作目录和暂存区都不会被改变,只是本地仓库中的文件回滚到当时的那个版本
--mixed 默认选项。回滚暂存区和本地仓库,但工作目录不受影响
--hard  本地仓库,暂存区和工作目录都回滚到指定的提交,该选项非常危险

回滚前的状态

git reset --soft HEAD~ 执行的效果

git reset --mixed HEAD~ 执行的效果

git reset --hard HEAD~ 执行的效果

[root@gitlab testproject]#cat f1.txt
v1
[root@gitlab testproject]#git commit -m v1
[master (root-commit) 0cc266f] v1
1 file changed, 1 insertion(+)
 create mode 100644 f1.txt
[root@gitlab testproject]#git status
On branch master
nothing to commit, working tree clean
[root@gitlab testproject]#echo v2 > f1.txt
[root@gitlab testproject]#git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
    modified:   f1.txt
no changes added to commit (use "git add" and/or "git commit -a")
[root@gitlab testproject]#git add .
[root@gitlab testproject]#git commit -m v2
[master 6fd0263] v2
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab testproject]#cat f1.txt
v2
[root@gitlab testproject]#git log
commit 6fd026348697f81baee6a1e3cb8032e39c5b073d (HEAD -> master)
Author: wangxiaochun <root@wangxiaochun.com>
Date:   Fri Sep 1010:00:27 2021+0800
    v2
commit 0cc266fec574873d01aa2e1c4d82bc9da3d6f61d
Author: wangxiaochun <root@wangxiaochun.com>
Date:   Fri Sep 1009:59:48 2021+0800
    v1
[root@gitlab testproject]#git reset --hard HEAD^
HEAD is now at 0cc266f v1
[root@gitlab testproject]#cat f1.txt
v1
[root@gitlab testproject]#git log
commit 0cc266fec574873d01aa2e1c4d82bc9da3d6f61d (HEAD -> master)
Author: wangxiaochun <root@wangxiaochun.com>
Date:   Fri Sep 1009:59:48 2021+0800
    v1
[root@gitlab testproject]#echo v2 > f1.txt
[root@gitlab testproject]#git add .
[root@gitlab testproject]#git commit -m v2
[master 4a07d95] v2
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab testproject]#echo v3 > f1.txt
[root@gitlab testproject]#git add .
[root@gitlab testproject]#git commit -m v3
[master 0169b85] v3
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab testproject]#git log
commit 0169b85667f3f157659c88260facc36e201f7271 (HEAD -> master)
Author: wangxiaochun <root@wangxiaochun.com>
Date:   Fri Sep 1010:04:06 2021+0800
    v3
commit 4a07d953fcc779d9d0b05a7fd86f90259863c821
Author: wangxiaochun <root@wangxiaochun.com>
Date:   Fri Sep 1010:03:47 2021+0800
    v2
commit 0cc266fec574873d01aa2e1c4d82bc9da3d6f61d
Author: wangxiaochun <root@wangxiaochun.com>
Date:   Fri Sep 1009:59:48 2021+0800
    v1
[root@gitlab testproject]#cat f1.txt
v3
#指定回滚至指定版本
[root@gitlab testproject]#git reset --hard 0cc266
HEAD is now at 0cc266f v1
[root@gitlab testproject]#cat f1.txt
v1

2.4.2.9.2 git revert

如果我们修改了某些内容,已经commit到本地仓库,并且push到远程仓库了,这种情况下想把本地和远程仓库都回退到某个版本,该怎么做呢?

前面用git reset只是在本地仓库中回退版本,而远程仓库的版本不会变化,这样,即使本地reset了,但如果再次git pull,那么,远程仓库的内容又会和本地之前版本的内容进行merge,造成回退失败。

对于已经把代码push到远程仓库,你退回本地代码其实也想同时退回线上代码,回滚到某个指定的版本,线上线下代码保持一致。git revert用于撤销某次操作,此次操作之前和之后的commit和history都会保留,即用一个新提交来消除一个历史提交所做的任何修改。

revert之后你的本地代码会回滚到指定的历史版本,然后再git push。

git revert 用法

git revert HEAD   #撤销前一次commit,会交互式打开文本编辑器提示输入提交信息
git revert HEAD --no-edit  #非交互式撤销前一次提交
git revert HEAD^  #撤销前前一次commit
git revert commit <commit> #撤销指定的版本,撤销也会作为一次提交进行保存。

reset和revert区别

git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
git reset是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容跟要
revert的内容正好相反,能够抵消要被revert的内容。
2.4.2.10 创建分支和合并分支

各种分支模型

#查看分支,默认只有master分支
[root@gitlab testproject]#git branch
* master
[root@gitlab testproject]#echo master data v1.0 > f1.txt
[root@gitlab testproject]#echo f2.txt > f2.txt
[root@gitlab testproject]#git commit -am 'add tow files'
#创建并切换新分支dev
[root@gitlab testproject]#git checkout -b dev
#查看分支
[root@gitlab testproject]#git branch
* dev
  master
[root@gitlab testproject]#ls
f1.txt  f2.txt
[root@gitlab testproject]#cat f1.txt
master data v1.0
[root@gitlab testproject]#cat f2.txt
f2.txt
[root@gitlab testproject]#echo dev data v1.0 > f1.txt
[root@gitlab testproject]#git commit -am 'modify f1.txt'
#只切换回原分支,修改数据
[root@gitlab testproject]#git checkout  master
[root@gitlab testproject]#echo f1.txt master data v2.0 > f1.txt
[root@gitlab testproject]#git commit -am "f1.txt v2.0"
[root@gitlab testproject]#git log  --pretty-oneline --graph --all
#切换分支至dev
[root@gitlab testproject]#git checkout dev
#合并master分支到当前分支dev
#交互式合并
[root@gitlab testproject]#git merge master
#或者非交互式
[root@gitlab testproject]#git merge master -m "merge master"
[root@gitlab testproject]#cat f1.txt
<<<<<<< HEAD
f1.txt dev data v1.0
=======
f1.txt master data v2.0
>>>>>>> master
#平行分支(有多次独立的提交的多个分支)中因为不同分支中同一个文件内容不同,会出现冲突,需要手动解决
冲突,并重新add和commit
[root@gitlab testproject]#git merge master
Auto-merging f1.txt
CONFLICT (content): Merge conflict in f1.txt
Automatic merge failed; fix conflicts and then commit the result.
[root@gitlab testproject]#vim f1.txt
[root@gitlab testproject]#cat f1.txt
f1.txt dev data v1.0
f1.txt master data v2.0
[root@gitlab testproject]#git commit -am 'merge master'
[root@gitlab testproject]#git log --pretty=oneline  --graph --all
2.4.2.11 修改分支名称
[root@gitlab testproject]#git branch
  dev
* master
[root@gitlab testproject]#git checkout dev
Switched to branch 'dev'
#修改当前分支名称为main
[root@gitlab testproject]#git branch -M main
[root@gitlab testproject]#git branch
* main
  master

2.4.2.12 当前状态打 tag 并利用 tag 回滚

[root@gitlab testproject]#echo v1.0 > a.txt;git add .;git commit -m v1.0
[main 0fba09a] v1.0
1 file changed, 1 insertion(+)
[root@gitlab testproject]#git tag v1.0
[root@gitlab testproject]#git tag
v1.0
[root@gitlab testproject]#echo v2.0 > a.txt;git add .;git commit -m v2.0
[main f0153a6] v2.0
1 file changed, 1 insertion(+), 1 deletion(-)
[root@gitlab testproject]#git tag v2.0
[root@gitlab testproject]#git tag
v1.0
v2.0
[root@gitlab testproject]#git show v1.0
commit 0fba09a8319f4c671be711f863ae12d44fd451a9 (tag: v1.0)
Author: wangxiaochun <29308620@qq.com>
Date:   Tue Feb 0223:11:02 2020+0800
    v1.0
diff--git a/a.txt b/a.txt
index e69de29..6b3126c 100644
--- a/a.txt
+++ b/a.txt
@@ -0,0 +1 @@
+v1.0
[root@gitlab testproject]#git reset --hard v1.0
HEAD is now at 0fba09a v1.0
[root@gitlab testproject]#cat a.txt
v1.0
2.4.2.13 本地代码提交给公用仓库码云
#在本机创建项目
[root@centos8 ~]#mkdir /data/linux;cd /data/linux
[root@centos8 linux]#git init
[root@centos8 linux]#git config --global user.name "wangxiaochun"
[root@centos8 linux]#git config --global user.email "29308620@qq.com"
[root@centos8 linux]#echo Hello,git > hello.txt
[root@centos8 linux]#git add .
[root@centos8 linux]#git commit -m "v1.0"
#先注册并登录码云,创建名称为linux的仓库后,可以执行下面操作建立本地仓库和远程码云的联系
[root@centos8 linux]#git remote add origin https://gitee.com/lbtooth/linux.git
#推送master分支同步至码云
[root@centos8 linux]#git push -u origin main:master
Username for'https://gitee.com': 用户名
Password for'https://lbtooth@gitee.com': 密码
[root@centos8 linux]#git remote
origin
[root@centos8 linux]#git remote -v
origin  https://gitee.com/lbtooth/linux.git (fetch)
origin  https://gitee.com/lbtooth/linux.git (push)
#和码云同步至本地
[root@centos8 linux]#git pull origin master
#删除关联
[root@centos8 linux]#git remote remove origin
[root@centos8 linux]#git remote -v

2.5 公有云仓库

git 创建本地仓库后,可以将本地仓库和远程仓库进行同步.实现网络共享和备份

远程仓库可以分为公有云仓库和私有仓库

公有云仓库: 如github,gitee等,免费给个人或公司用使用,依赖互联网私有仓库: 如gitlab,适合于公司等组织内部网络使用

2.5.1 使用 github

范例: 使用 github 创建仓库并将本地仓库上传至远程

[root@gitlab testproject]#git remote add origin git@github.com:lbtooth/hello-
world.git
[root@gitlab testproject]#git remote
origin
[root@gitlab testproject]#git remote  -v
origin  git@github.com:lbtooth/hello-world.git (fetch)
origin  git@github.com:lbtooth/hello-world.git (push)
[root@gitlab testproject]#git push -u origin master
The authenticity of host 'github.com (52.74.223.119)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,52.74.223.119' (RSA) to the list of known
hosts.
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
[root@gitlab testproject]#git-keygen
[root@gitlab testproject]#cat ~/.ssh/id_rsa.pub
ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQDgAoGJ4si2K3lz3xe1LJ8mUenQ6bKRhSjoQkDT6ALUp0vILsjH
EywgHhoA3gmHY3Vy+QXPhqDWQ/4zT3+e0DrEcXiWv+HuBOU07QtJgk4/r2NXg6dDfx3snmdbOpfIeTPM
gRmZxZDLstk2m8RqEv3Bh4SxsIrGHd/AIlDnolqPrn0zorXJYDjJtN014ESPF5XPfewkZAly9TYBowbG
t0EFIYcwIsEVEH21rl/cXoTJ3L0lEQqlIZtJPEWMGPW4qbs8RIcC9O1Xnm1kdDrC6dvSERrdh3FDDkhF
CtcNqE72iikjjNxkQkeSDN392GEVnDhwhm3jM2xPNcZOs9F3OPnX root@ubuntu1804.wang.org

[root@gitlab testproject]#git push -u origin master
Counting objects: 11, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (11/11), 825 bytes | 825.00 KiB/s, done.
Total 11 (delta 0), reused 0 (delta 0)
To github.com:lbtooth/hello-world.git
 * [new branch]      master -> master
Branch 'master'set up to track remote branch 'master' from 'origin'.

2.5.2 使用 gitee

范例: 国内码云创建仓库

2.6 实战案例: 元宇宙创业史

2.6.1 起步: 个人小型项目

2.6.1.1 初始化项目

想要让 git 对一个目录进行版本控制需要以下步骤:

#进入要管理的文件夹
cd  /meta-project
#执行初始化命令
git init
#管理目录下的文件状态
vim index.html
git status
#管理指定文件
git add 文件名
git add .
#个人信息配置:用户名和邮箱,只需配置一次即可
git config --global user.name "wangxiaochun"
git config --global user.email "wang@qq.com"
git config --global color.ui true
#提交
git commit -m"项目开发基本功能v0.0.1"
#查看版本记录
git log
#记录图形展示
git log --pretty=oneline --graph--all
git log --graph--pretty=format:"%h %s"
git log --graph--pretty=format:'%h -%d %s (%an, %cd)'
2.6.1.2 开发新功能
git add .
git commit -m '添加AR功能'
2.6.1.3 版本回退

发现新功能审查有问题,回滚至之前版本

git log                       #查看所有的提交记录
git reflog                    #查看所有的历史提交记录
git reset --hard  <commitID>  #回退到指定的commitID

新功能过审后,再回滚至之后版本,即上面'添加AR功能'的版本

git reflog                   #查看所有的历史提交记录
git reset --hard <commitID>  #回退到指定的commitID

2.6.2 业务增长: 发布特定版本和紧急修复 bug

有一些特定的"轻奢"用户需要特殊的新特性,但对当前版本不希望改变

创建新分支可以给使用者提供多个不同的分支版本,意味着可以把当前工作从主线版本分离开来,以免影响主线版本的开发。

#查看分支和当前分支
git branch
#创建分支
git branch dev
#切换分支
git checkout dev
vim index.html
git add .
git commit -m'添加新特性'
#删除分支
git branch -d debug
#将指定分支合并至当前分支,可能产生冲突
git merge <要合并的分支>
git merge dev  #将dev的最新代码合并到当前分支

2.6.3 加班: 实现多台主机的远程协作开发

项目很成功,赚得了第一桶金,购置了新的公办场地,招聘了多个员工协同开发工作原有电脑的配置已显不足,为支持更大项目的需要,配置了新电脑,继续开发同时时间紧张,回家也需要加班开发

2.6.3.1 注册和创建的远程软件仓库

首先,需要注册github或gitee等仓库账号,并创建远程仓库,然后再执行如下命令,将代码上传到仓库注意: 新建仓库时,选择不初始化仓库

2.6.3.2 将本地仓库同步至远程仓库
#给远程仓库起别名
git remote add origin <远程仓库地址>
#将当前分支的代码推送至远程
git push -u origin 分支
#推送当前已有项目到gitee仓库
git remote add origin https://gitee.com/lbtooth/meta-project.git
git push -u origin "master"
#关联远程仓库
[root@ubuntu2004 meta-project]#git remote add origin
https://gitee.com/lbtooth/meta-project.git
#也可以将用户和密码同时关联
[root@ubuntu2004 meta-project]#git remote add origin https://<用户名>:<密码
>@gitee.com/lbtooth/meta-project.git
#查看关联
[root@ubuntu2004 meta-project]#git remote
origin
[root@ubuntu2004 meta-project]#git remote -v
origin  https://gitee.com/lbtooth/meta-project.git (fetch)
origin  https://gitee.com/lbtooth/meta-project.git (push)
#推送所有分支到远程仓库
[root@ubuntu2004 meta-project]#git push -u origin --all
Username for'https://gitee.com': lbtooth
Password for'https://lbtooth@gitee.com':
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.3]
remote: Create a pull request for'debug' on Gitee by visiting:
remote:     https://gitee.com/lbtooth/meta-
project/pull/new/lbtooth:debug...lbtooth:master
To https://gitee.com/lbtooth/meta-project.git
 * [new branch]      debug -> debug
Branch 'dev'set up to track remote branch 'dev' from 'origin'.
Branch 'master'set up to track remote branch 'master' from 'origin'.
#或者只推送dev分支
[root@ubuntu2004 meta-project]#git checkout dev
[root@ubuntu2004 meta-project]#git push origin dev

查看gitee网站可以看到仓库有文件上传成功

2.6.3.3 在新电脑初次使用下载远程仓库的代码并继续开发

#克隆远程仓库代码,自动实现实现git remote add origin 远程仓库地址
git clone <远程仓库地址>
#切换分支
git checkout 分支
#在公司下载完代码后,继续开发,切换到dev分支进行开发
git checkout dev
#把master分支合并到dev
git merge master
#修改代码
git add .
#提交代码
git commit -m'继续开发新功能'
git push origin dev

示例: 新电脑同步远程仓库到本地

[root@ubuntu2004 ~]#cd /
#公有仓库直接下载即可
[root@ubuntu2004 meta-project]#git clone https://gitee.com/lbtooth/meta-
project.git
#如果是私有仓库,还需要提供用户和密码
[root@ubuntu2004 meta-project]#git clone https://<用户名>:<密码
>@gitee.com/lbtooth/meta-project.git
#确认分支
[root@ubuntu2004 meta-project]#git branch
* master
[root@ubuntu2004 meta-project]#git checkout -b dev
#拉取dev分支
[root@ubuntu2004 meta-project]#git pull origin dev
#确认新代码已经同步到本机
[root@ubuntu2004 meta-project]#cat index.html
#个人信息配置:用户名和邮箱,只需配置一次即可
[root@ubuntu2004 meta-project]#git config --global user.email "wang@qq.com"
[root@ubuntu2004 meta-project]#git config --global user.name "wang"
[root@ubuntu2004 meta-project]#git config --global color.ui true

# 继续提交

[root@ubuntu2004 meta-project]#vim index.html
[root@ubuntu2004 meta-project]#git add .
[root@ubuntu2004 meta-project]#git commit -m '继续开发新功能'

# 同步到远程仓库

[root@ubuntu2004 meta-project]#git push origin dev
Username for'https://gitee.com': lbtooth
Password for'https://lbtooth@gitee.com':
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 361 bytes | 361.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.3]
To https://gitee.com/lbtooth/meta-project.git
   6be3e4d..43b9a43  dev -> dev
2.6.3.4 下班回到家继续加班
#切换到dev分支进行开发
git checkout dev
#拉取最新代码
git pull origin dev
#等价于
git fetch origin dev
git merge origin/dev
#继续开发
git add .
#提交代码
git commit -m'在家加班'
#推送至远程
git push origin dev
2.6.3.5 到公司继续开发
#切换到dev分支进行开发
git checkout dev
#拉最新代码,不必再clone,只需要通过pull获取最新代码即可
git pull origin dev
#继续开发.提交代码
git add .
git commit -m'上班工作'
#推送代码到仓库
git push origin dev
2.6.3.6 开发完毕,要上线
#将dev分支合并到master,进行上线
git checkout master
git merge dev
git push origin master
#把dev分支也推送到远程
git checkout dev
git merge master
git push origin dev
2.6.3.7 免密码登录

通过HTTP/HTTPS实现

#原来的地址:
https://gitee.com/lbtooth/meta-project.git
#修改的地址:
https://用户名:密码@gitee.com/lbtooth/meta-project.git
git remote add origin https://用户名:密码@gitee.com/lbtooth/meta-project.git
git push origin master

SSH 实现

#生成公钥和私钥(默认放在 ~/.ssh目录下,id_rsa.pub公钥、id_rsa私钥)
ssh-keygen
#拷贝公钥的内容,并设置到gitee或github中
cat id_rsa.pub
#在git本地中配置ssh地址
git remote add origin git@gitee.com:lbtooth/meta-project.git
#以后使用以下即可
git push origin master

2.6.4 多版本管理:标签管理

虽然每次commit,都会生成一个commit id,但此方式无疑是不方便标记和记忆的

git标签就是对指定的commit的一次快照,相当于给commit ID起了一个容易记忆的名称,可以做为进度的里程碑的标记

git tag 便于后续将特定时期的代码快速取出。

在代码发布时可以使用标签发布。

#对当前最新提交的代码创建标签,-a标签名称,-m标签描述
git tag -a"v2.0"-m"新版本2.0"
#创建标签,指定commit ID
git log #查看Commit ID
git tag -a"v1.0" <Commit ID> -m"正式版本1.0"
#查看标签详情
git tag
git log -l
#同步所有标签到远程仓库
git push origin --tags

范例:

#当前状态创建tag
[root@ubuntu2004 meta-project]#git tag -a "v1.0" -m "正式版本1.0"
#查看tag信息
[root@ubuntu2004 meta-project]#git show v1.0
tag v1.0
Tagger: wang <wang@qq.com>
Date:   Tue Jul 1910:01:29 2022+0000
正式版本1.0
commit 61a19a66264171fb73600166384ea828e00a5818 (HEAD -> master, tag: v1.0,
origin/master)
Author: wang <wang@qq.com>
Date:   Tue Jul 1909:18:38 2022+0000
删除Hello.java
diff--git a/Hello.java b/Hello.java
deleted file mode 100644
index 110b1e6..0000000
--- a/Hello.java
+++ /dev/null
@@ -1+0,0 @@
-Hello v1.0
#查看commit ID
[root@ubuntu2004 meta-project]#git log
[root@ubuntu2004 meta-project]#git reflog
#为指定commit id创建tag
[root@ubuntu2004 meta-project]#git tag -a 'v0.0.1' d9c6b575702441fd -m '初始发布'
#同步所有tag到远程仓库
[root@ubuntu2004 meta-project]#git push origin --tags
#拉取所有远程仓库的tag
[root@ubuntu2004 meta-project]#ggit pull origin --tags

3 私有软件仓库 GitLab

3.1 GitLab 介绍

GitLab 是一个基于Ruby on Rails构建用于仓库管理系统的开源项目,使用Git作为代码管理工具,提供了Web界面进行访问公开的或者私有的项目

GitLab 优势

  • 开源免费

  • 可以作为 Git 代码仓库

  • 提供了方便易用的 Web 管理界面

  • 支持离线提交

  • 安全性高, 可以对不同的用户设置不同的权限,并且支持不同用户只能访问特定的代码,实现代码部分可见

3.2 GitLab 安装

3.2.1 GitLab 架构

Gitlab 是一个复杂的系统,由很多应用组成

https://panlw.github.io/15365441001781.html

Gitlab的服务构成

Nginx:静态web服务器

gitlab-shell:用于处理Git命令和修改authorized keys列表

  • gitlab-workhorse:轻量级的反向代理服务器它旨在充当智能反向代理,以帮助整个 GitLab 加速 postgresql:数据库

  • redis:缓存数据库

sidekiq:用于在后台执行队列任务(异步执行)

unicorn: An HTTP server for Rack applications, GitLab Rails应用是托管在这个服务器上面的

3.2.2 安装 GitLab 要求

Gitlab硬件和软件的环境要求:

https://docs.gitlab.com/ce/install/requirements.html

Gitlab 服务的安装文档:

https://docs.gitlab.com/ce/install/

硬件配置要求较高:

测试环境:内存4G以上

生产环境:建议CPU2C以上,内存8G以上,磁盘10G以上配置,和用户数有关

数据库要求:

从GitLab 12.1 开始不再支持MySQL,只支持PostgreSQL

3.2.3 安装前准备

3.2.3.1 Ubuntu 系统环境安装前准备

3.2.3.1.1 配置 ubuntu 远程连接

[wang@ubuntu1804 ~]$ sudosu- root
[sudo] password for wang:
root@ubuntu:~# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
[root@ubuntu1804 ~]# vim /etc/ssh/sshd_config
PermitRootLogin yes
[root@ubuntu1804 ~]#systemctl restart sshd
3.2.3.1.2 配置ubuntu 主机名
[root@ubuntu1804 ~]#hostnamectl set-hostname gitlab.wang.org
3.2.3.1.3 配置ubuntu 仓库

配置阿里云或清华大学等国内镜像仓库实现加速

[root@ubuntu1804 ~]#vim /etc/apt/sources.list
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe
multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted
universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted
universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main
restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted
universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main
restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted
universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main
restricted universe multiverse
debhttps://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted
universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main
restricted universe multiverse
3.2.3.2 RHEL 系统环境安装前准备

基于最小化服务器安装,建议修改配置如下:

[root@centos ~]# wget -O /etc/yum.repos.d/epel.repo
http://mirrors.aliyun.com/repo/epel-7.repo
[root@centos ~]# systemctl disable firewalld
[root@centos ~]# sed -i '/SELINUX/s/enforcing/disabled/' /etc/sysconfig/selinux
[root@centos ~]# hostnamectl set-hostname gitlab.example.com
[root@centos ~]# reboot

3.2.4 GitLab 安装

gitlab 安装有多种方式,下面选择包安装方式

https://docs.gitlab.com/ce/install/

3.2.4.1 安装 GitLab

官方gitlab 包下载链接

https://packages.gitlab.com/gitlab

GitLab-CE 安装包官方下载地址:

https://packages.gitlab.com/gitlab/gitlab-ce

yum源清华大学下载地址:

https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/

CentOS 的yum源

ubuntu 的deb源

https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/

范例:下载并安装 gitlab

# 新版下载和安装

[root@ubuntu2004 ~]#wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-
ce/ubuntu/pool/bionic/main/g/gitlab-ce/gitlab-ce_14.1.0-ce.0_amd64.deb
[root@ubuntu1804 ~]#dpkg -i gitlab-ce_14.1.0-ce.0_amd64.deb

# 旧版下载和安装

[root@ubuntu1804 ~]#wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-
ce/ubuntu/pool/bionic/main/g/gitlab-ce/gitlab-ce_11.11.8-ce.0_amd64.deb
[root@ubuntu1804 ~]#dpkg -i gitlab-ce_11.11.8-ce.0_amd64.deb

3.2.4.2 修改 GitLab 配置

gitlab相关的目录:

/etc/gitlab #配置文件目录
/run/gitlab #运行目录,存放很多的数据库文件
/opt/gitlab #安装目录
/var/opt/gitlab #数据目录,源代码就存放在此目录
/var/log/gitlab #日志目录

范例: gitlab 初始化配置

[root@ubuntu1804 ~]#vim /etc/gitlab/gitlab.rb
[root@ubuntu1804 ~]#grep "^[a-Z]" /etc/gitlab/gitlab.rb
external_url 'http://gitlab.wang.org'#修改此行
#增加下面行(可以和上面行写在一起),可选邮件通知设置
gitlab_rails['smtp_enable'] =true
gitlab_rails['smtp_address'] ="smtp.qq.com"
gitlab_rails['smtp_port'] =465
gitlab_rails['smtp_user_name'] ="29308620@qq.com"
gitlab_rails['smtp_password'] ="授权码"
gitlab_rails['smtp_domain'] ="qq.com"
gitlab_rails['smtp_authentication'] ="login"
gitlab_rails['smtp_enable_starttls_auto'] =true
gitlab_rails['smtp_tls'] =true
gitlab_rails['gitlab_email_from'] ="29308620@qq.com"
#新版中增加下面行,给root用户指定初始密码才能登录
gitlab_rails['initial_root_password'] ="12345678"
#名称解析
[root@ubuntu1804 ~]#vim /etc/hosts
10.0.0.100 gitlab.wang.org

由于 Gitlab 主机功能是代码托管,默认有些额外的组件比较消耗资源,如果暂时不使用可以考虑关闭

范例: 将不需要使用的组件都设定为false

vim /etc/gitlab/gitlab.rb
prometheus['enable'] =false
prometheus['monitor_kubernetes'] =false
alertmanager['enable'] =false
node_exporter['enable'] =false
redis_exporter['enable'] =false
postgres_exporter['enable'] =false
gitlab_exporter['enable'] =false
prometheus_monitoring['enable'] =false
grafana['enable'] =false
3.2.4.3 初始化和启动服务

执行配置并启动服务:

#每次修改完配置文件都需要执行此操作
[root@ubuntu1804 ~]#gitlab-ctl reconfigure

2.2.4.4 验证 GitLab 启动完成

# 新版服务

[root@ubuntu1804 ~]#gitlab-ctl status
run: alertmanager: (pid 12495) 73s; run: log: (pid 12138) 144s
run: gitaly: (pid 12374) 76s; run: log: (pid 11439) 257s
run: gitlab-exporter: (pid 12388) 76s; run: log: (pid 11915) 163s
run: gitlab-workhorse: (pid 12349) 77s; run: log: (pid 11840) 181s
run: grafana: (pid 12514) 73s; run: log: (pid 12286) 96s
run: logrotate: (pid 11357) 270s; run: log: (pid 11365) 269s
run: nginx: (pid 11846) 177s; run: log: (pid 11860) 176s
run: node-exporter: (pid 12363) 76s; run: log: (pid 11898) 170s
run: postgres-exporter: (pid 12507) 73s; run: log: (pid 12164) 140s
run: postgresql: (pid 11570) 252s; run: log: (pid 11585) 249s
run: prometheus: (pid 12397) 75s; run: log: (pid 11960) 152s
run: puma: (pid 11754) 196s; run: log: (pid 11762) 193s
run: redis: (pid 11387) 264s; run: log: (pid 11395) 263s
run: redis-exporter: (pid 12390) 75s; run: log: (pid 11936) 157s
run: sidekiq: (pid 11772) 190s; run: log: (pid 11786) 187s

# 旧版服务

[root@ubuntu1804 ~]#gitlab-ctl status
run: alertmanager: (pid 29801) 117s; run: log: (pid 29411) 135s
run: gitaly: (pid 29575) 120s; run: log: (pid 28084) 222s
run: gitlab-monitor: (pid 29659) 119s; run: log: (pid 29196) 151s
run: gitlab-workhorse: (pid 29616) 120s; run: log: (pid 28848) 173s
run: logrotate: (pid 28923) 166s; run: log: (pid 29008) 163s
run: nginx: (pid 28851) 172s; run: log: (pid 28902) 169s
run: node-exporter: (pid 29638) 119s; run: log: (pid 29107) 157s
run: postgres-exporter: (pid 29817) 116s; run: log: (pid 29479) 131s
run: postgresql: (pid 28231) 217s; run: log: (pid 28266) 214s
run: prometheus: (pid 29767) 118s; run: log: (pid 29335) 139s
run: redis: (pid 27937) 229s; run: log: (pid 27974) 227s
run: redis-exporter: (pid 29668) 118s; run: log: (pid 29258) 145s
run: sidekiq: (pid 28742) 180s; run: log: (pid 28797) 177s
run: unicorn: (pid 28653) 186s; run: log: (pid 28698) 183s
3.2.4.5 验证端口及状态

80端口是在初始化gitlib的时候启动的,因此如果之前有程序占用了相关端口,就会导致初始化失败或无法访问

[root@ubuntu1804 ~]#lsof -i :80
COMMAND   PID       USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   28851       root    7u  IPv4  88801      0t0  TCP *:http (LISTEN)
nginx   28852 gitlab-www    7u  IPv4  88801      0t0  TCP *:http (LISTEN)
nginx   28853 gitlab-www    7u  IPv4  88801      0t0  TCP *:http (LISTEN)
2.2.4.6 gitlab的常用命令
gitlab-rails #用于启动控制台进行特殊操作,如修改管理员密码、打开数据库控制台( gitlab-rails
dbconsole)等
gitlab-psql #数据库命令行
gitlab-rake #数据备份恢复等数据操作
#客户端命令行操作行
gitlab-ctl
gitlab-ctl reconfigure  #修改过配置后需要执行重新配置
gitlab-ctl stop#停止gitlab
gitlab-ctl start#启动gitlab
gitlab-ctl restart#重启gitlab
gitlab-ctl status       #查看组件运行状态
gitlab-ctl tail         #查看所有日志
gitlab-ctl tail nginx   #查看某个组件的日志
gitlab-ctl service-list #列出服务

范例:

[root@ubuntu1804 ~]#gitlab-psql
psql (9.6.11)
Type "help"for help.
gitlabhq_production=# help
You are using psql, the command-line interface to PostgreSQL.
Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit
gitlabhq_production=# \db
         List of tablespaces
    Name    |    Owner    | Location
------------+-------------+----------
 pg_default | gitlab-psql |
 pg_global  | gitlab-psql |
(2 rows)
gitlabhq_production-# \q
[root@ubuntu1804 ~]#

范例: 查看服务列表

[root@gitlab ~]#gitlab-ctl service-list
alertmanager*
gitaly*
gitlab-exporter*
gitlab-workhorse*
grafana*
logrotate*
nginx*
node-exporter*
postgres-exporter*
postgresql*
prometheus*
puma*
redis*
redis-exporter*
sidekiq*
3.2.4.7 一键安装 GitLab 脚本
#!/bin/bash
#
#********************************************************************
#Author:            wangxiaochun
#QQ:                29308620
#Date:              2020-02-10
#FileName:          install_gitlab.sh
#URL:               http://www.wangxiaochun.com
#Description:       The test script
#Copyright (C):     2020 All rights reserved
#********************************************************************
#说明:安装GitLab 服务器内存建议至少4G,root密码至少8位
GITLAB_VERSION=14.1.0
URL="https://mirrors.tuna.tsinghua.edu.cn/gitlab-
ce/ubuntu/pool/bionic/main/g/gitlab-ce/gitlab-ce_${GITLAB_VERSION}-
ce.0_amd64.deb"
#URL="https://mirrors.tuna.tsinghua.edu.cn/gitlab-
ce/ubuntu/pool/bionic/main/g/gitlab-ce/gitlab-ce_12.3.5-ce.0_amd64.deb"
#URL="https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el8/gitlab-ce-14.1.5-
ce.0.el8.x86_64.rpm"
#URL="https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-14.1.5-
ce.0.el7.x86_64.rpm"
GITLAB_ROOT_PASSWORD=12345678
SMTP_PASSWORD=xxxxxxxxxxxxxx
HOST=gitlab.wang.org
#HOST=`hostname -I|awk '{print $1}'`
. /etc/os-release
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo-n"$1" && $MOVE_TO_COL
echo-n"["
if [ $2="success"-o$2="0" ] ;then
${SETCOLOR_SUCCESS}
echo-n$"  OK  "
elif [ $2="failure"-o$2="1"  ] ;then
${SETCOLOR_FAILURE}
echo-n$"FAILED"
else
${SETCOLOR_WARNING}
echo-n$"WARNING"
fi
${SETCOLOR_NORMAL}
echo-n"]"
echo
}
install_gitlab() {
wget-P /usr/local/src/ $URL || { color  "下载失败!"1 ;exit ; }
PACK="/usr/local/src/${URL##*/}"
if [ $ID="centos"-o$ID="rocky" ];then
        yum -y install $PACK
else
        dpkg -i$PACK
fi
if [ $?-eq0 ];then
            color "安装gitlab完成!"0
else
            color "安装gitlab失败!"1
exit
fi
}
config_gitlab() {
sed-i.bak  "/^external_url.*/c external_url \'http://$HOST\'"
/etc/gitlab/gitlab.rb
cat  >> /etc/gitlab/gitlab.rb <<EOF
gitlab_rails['smtp_enable'] =true
gitlab_rails['smtp_address'] ="smtp.qq.com"
gitlab_rails['smtp_port'] =465
gitlab_rails['smtp_user_name'] ="29308620@qq.com"
gitlab_rails['smtp_password'] ="$SMTP_PASSWORD"
gitlab_rails['smtp_domain'] ="qq.com"
gitlab_rails['smtp_authentication'] ="login"
gitlab_rails['smtp_enable_starttls_auto'] =true
gitlab_rails['smtp_tls'] =true
gitlab_rails['gitlab_email_from'] ="29308620@qq.com"
gitlab_rails['initial_root_password'] ="$GITLAB_ROOT_PASSWORD"
EOF
    gitlab-ctl reconfigure
    gitlab-ctl status
if [ $?-eq0 ];then
echo
        color "Gitlab安装完成!"0
echo"------------------------------------------------------------------
-"
echo-e"请访问链接: \E[32;1mhttp://$HOST/\E[0m"
echo-e"用户和密码: \E[32;1mroot/${GITLAB_ROOT_PASSWORD}\E[0m"
else
        color "Gitlab安装失败!"1
exit
fi
}
install_gitlab
config_gitlab
export GITLAB_HOME=/srv/gitlab
sudo docker run --detach \
  --hostname gitlab.example.com \
  --publish 443:443 --publish 80:80 --publish 22:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  --shm-size 256m \
  gitlab/gitlab-ee:latest
3.2.4.8 基于 Docker 安装 GitLab

3.3 GitLab 基本配置

3.3.1 首次登录 GitLab Web 界面修改密码

新版gitlab密码初始化官方帮助链接

https://docs.gitlab.com/omnibus/installation/index.html

浏览器访问 http://gitlab 服务器 IP/

在新版gitlab中第一次登录的界面发生变化,取消重设密码界面,需要直接输入用户和密码才能登录

#如果没有在配置文件中对密码做初始化设置,可以从以下文件找到初始密码
[root@ubuntu1804 ~]#cat /etc/gitlab/initial_root_password
# WARNING: This value is valid only in the following conditions
#          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment
variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`,
it was provided before database was seeded for the first time (usually, the first
reconfigure run).
#          2. Password hasn't been changed manually, either via UI or via command
line.
#
#          If the password shown here doesn't work, you must reset the admin
password following
https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-
password.
Password: t2c31Eqz4035tmrbAJFl/itm8aSkEHu87xGzluzsj/w=
# NOTE: This file will be automatically deleted in the first reconfigure run
after 24 hours.

新版登录界面,用root用户和配置文件中指定的密码或以上文件中的初始密码登录

新版登录后,也可以再次修改密码,注意:密码至少8位

使用用户 root 和上面设置的密码登录新版界面

新版登录首页

以下是旧版的首次登录web页面,必须先设置密码,密码要求最少8位

旧版界面

旧版登录首页

3.3.2 修改头像

登录gitlab后可能看到用户的头像不能正常显示,可以修改为自定义的头像

3.3.3 关闭账号注册功能

新版用户注册界面

关闭注册功能,先用root用户登录

Save Changes 后,再重新登录观察到注册界面不再显示

旧版中默认情况下也可以直接注册账号,基于安全目的,一般都会关闭此功能

取消账户注册功能之后点 save changes

重新登录,验证是否还有注册选项

2.3.4 修改邮箱地址

新版界面

确认收到邮件

确认邮件生效

查看邮件生效

修改个人资料的邮件地址

验证邮箱

旧版界面

登录邮箱帐号,验证注册信息

如下面,修改邮箱设置指定新的邮箱

重新登录后,可以看到邮箱的变化

删除旧的邮箱

3.4 GitLab 用户和组管理

3.4.1 用户管理

创建gitlab用户账户并登录

新版界面

创建用户成功后,用户邮箱会收到下面邮件

点上面的链接重设密码

登录成功,并且收到邮件

同样的方式再创建其他用户

旧版界面

如下图,填写用户信息

登录邮箱,可以看到注册邮件

使用第一次使用新账号登录要设置密码:

修改密码后,会收到修改密码的邮件

3.4.2 创建组

使用管理员root 或用户都可以创建group组

一个group组里面可以拥有多个project项目分支,可以将开发的用户添加到组里,再进行设置权限不同的组对应公司不同的开发项目或者服务模块

如果gitlab使用者的组织规模较大,每一个group组可以分别对应一个组织,如:某个分公司或部门如果gitlab使用者的组织规模较小, 每一个group组也可以对应一个项目或业务

不同的组中添加不同的开发人员帐号,即可实现对开发者实现权限的管理。

新版界面

基于安全,选择private

旧版界面

3.5 GitLab 项目管理

3.5.1 创建项目

项目project属于一个group组,即一般project对应一个项目中的功能模块或服务注意: 新建项目时不要进行初始化

新版界面

创建项目,指定项目属于组,并选择不进行初始化项目仓库

命令行指引

您还可以按照以下说明从计算机中上传现有文件。

Git 全局设置

git config --global user.name "Administrator"
git config --global user.email "admin@example.com"

创建一个新仓库

git clone http://gitlab.wang.org/dev/meta.git
cd meta
git switch -c main
touch README.md
git add README.md
git commit -m "add README"
git push -u origin main

推送现有文件夹

cd existing_folder
git init --initial-branch=main
git remote add origin http://gitlab.wang.org/dev/meta.git
git add .
git commit -m "Initial commit"
git push -u origin main

推送现有的 Git 仓库

cd existing_repo
git remote rename origin old-origin
git remote add origin http://gitlab.wang.org/dev/meta.git
git push -u origin --all
git push -u origin --tags

旧版界面

使用管理员创建项目:

创建后的项目效果:

3.5.2 将用户添加到组或项目

将用户添加到组或项目中,并指定不同的角色,可以获取不同的权限角色和权限官方帮助

https://docs.gitlab.com/ce/user/permissions.html

Gitlab用户在组里面有5种不同权限:

Guest: 可以创建issue、发表评论,不能读写版本库

  • Reporter:可以克隆代码,不能提交,QA、PM可以赋予这个权限

  • Developer:可以克隆代码、开发、提交、 push(非保护分支Protected branches),普通开发可以赋予这个权限

  • Maintainer:可以创建项目、添加tag、保护分支、添加项目成员、编辑项目,核心开发人员可以赋予这个权限

  • Owner:可以设置项目访问权限Visibility Level、删除项目、迁移项目、管理组成员,开发组组长可以赋予这个权限

在组中添加用户并指定角色

注意: 设为maintainer角色才能push代码,developer角色(对保护分支,如master)只能pull不能push

或者在项目中添加用户进行角色指定,此方式后续管理不太方便,不建议加用户到项目,建议将用户加入组中

旧版界面

3.5.3 使用项目

3.5.3.1 在项目中新建一个测试页面

用上面创建的用户wang登录,找到项目界面,在项目中新建文件

旧版界面

填写READE.md文件内容

新建项目文件

3.5.3.2 在linux客户端测试clone和提交项目

命令行指引

您还可以按照以下说明从计算机中上传现有文件。

Git 全局设置

git config --global user.name "Administrator"
git config --global user.email "admin@example.com"

创建一个新仓库

git clone http://gitlab.wang.org/dev/meta.git
cd meta
git switch -c main
touch README.md
git add README.md
git commit -m "add README"
git push -u origin main

推送现有文件夹

cd existing_folder
git init --initial-branch=main
git remote add origin http://gitlab.wang.org/dev/meta.git
git add .
git commit -m "Initial commit"
git push -u origin main

推送现有的 Git 仓库

cd existing_repo
git remote rename origin old-origin
git remote add origin http://gitlab.wang.org/dev/meta.git
git push -u origin --all
git push -u origin --tags

根据不同的情况,在另一台主机上执行下面操作

[root@ubuntu1804 ~]#cd /data
[root@ubuntu1804 data]#ls
lost+found
[root@ubuntu1804 data]#git clone
http://gitlab.wang.org/testgroup/testproject.git
Cloning into 'testproject'...
Username for'http://10.0.0.100': wang
Password for'http://wang@10.0.0.100':
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
[root@ubuntu1804 data]#ls -a
.  ..  lost+found  testproject
[root@ubuntu1804 data]#tree testproject/
testproject/
├── index.html
└── README.md
0 directories, 2 files
#设置用户名和邮箱
[root@ubuntu1804 data]#git config --global user.name "wangxiaochun"
[root@ubuntu1804 data]#git config --global user.email  "root@wangxiaochun.com"
[root@ubuntu1804 data]#cat ~/.gitconfig
[user]
        name = wangxiaochun
        email = root@wangxiaochun.com
[root@ubuntu1804 data]#vim testproject/
#修改项目文件
[root@ubuntu1804 data]#vim testproject/index.html
[root@ubuntu1804 data]#cat testproject/index.html
<h1>index.html v1 </h1>
<h1>index.html v2 </h1>
[root@ubuntu1804 data]#cd testproject/
[root@ubuntu1804 testproject]#git add .
[root@ubuntu1804 testproject]#git commit -m "v2"
[master 44dbd92] v2
1 file changed, 2 insertions(+), 1 deletion(-)
[root@ubuntu1804 testproject]#git push
Username for'http://10.0.0.100': wang
Password for'http://wang@10.0.0.100':
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 296 bytes | 296.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://10.0.0.100/testgroup/testproject.git
   928e057..44dbd92  master -> master
3.5.3.3 在windows 安装 git 客户端测试clone和提交项目

官网下载链接:

https://git-scm.com/download/win

3.5.3.4 Web端验证数据

3.5.3.5 实现 ssh 基于key验证的 git 访问
[root@centos8 ~]#ssh-keygen
[root@centos8 ~]#cat .ssh/id_rsa.pub
ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABgQDQerYDHH/IWvYfIzCiIvp9oHzCNVepAOcP37M3cmhz0NFnN655
cA66lp5j00qCOfjh9DFq4RNMUiL9XvqQ/Q4N7/ZLoUlVO2L3XPTTmwLtKg3snGExn0owj4B49wi5BTjs
wo9HOmf3Qh7KGHKO9VlG0O+/QFU8W1nySrPJvdi5mQaofqyXXMMsK2lIFgdDH0QhZcY3IkpC63BEhfgb
vnhlXjVjwepu8lcJYWU8We30XOm6j6/dIjdP+AzamdiIntj/Oby5P0yuN/kNYjQvsbiaw1nO8z+Z/cqA
4e2pmmA7sHwUIqUve5RL7+DDue71sL7aODWQjcgOkRj5BYSNWcavF1hispfQIhakz9pdROhB90wXVcyr
RehnHK73IMGc+abu0/9oz8e58LyEaRdSaQ6nRywcso/rmX1aoH/KTFmRe42O+pOeri1KzbSfrrTIQmma
0wF9k1YQEoTI0fpQpyvGWM5nGtEm7W+iG0zPiMaDzAzGcetu8AkJyFy37GwuDL8=
root@centos8.wang.org

[root@centos8 ~]#cd /opt
[root@centos8 opt]#ls
[root@centos8 opt]#git clone git@10.0.0.100:testgroup/testproject.git
Cloning into 'testproject'...
The authenticity of host '10.0.0.100 (10.0.0.100)' can't be established.
ECDSA key fingerprint is SHA256:SCZC/wgETlcNAvmd1gaG8Tvb4sR53VzbaX1MHKi9GLY.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.100' (ECDSA) to the list of known hosts.
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 3
Receiving objects: 100% (6/6), done.

3.5.3.6 保护分支

默认master 分支被保护,开发者角色无法对被保护的分支提交代码

也可以将其它分支进行保护,防止指定分支被破环

3.5.3.7 合并分支

由于普通开发者无法直接提交代码至master分支,可以先创建其它分支如dev,再提交代码到dev分支,接下来申请将dev 分支合并至master分支,管理者收到请求,经过审核没有问题进行批准合并, 最终实现master 代码的更新

3.6 GitLab 的数据备份和恢复

官方帮助:

https://docs.gitlab.com/ee/raketasks/backup_restore.html

3.6.1 备份相关配置文件

/etc/gitlab/gitlab.rb
/etc/gitlab/gitlab-secrets.json #双因子验证等使用此文件

备份配置文件命令

gitlab-ctl backup-etc --backup-path <DIRECTORY>
#如果不指定--backup-path <DIRECTORY>,则默认备份至/etc/gitlab/config_backup/

范例:备份配置文件命令

[root@ubuntu1804 ~]#gitlab-ctl backup-etc
Could not find'/etc/gitlab/config_backup' directory. Creating.
Running configuration backup
Creating configuration backup archive: gitlab_config_1627267534_2021_07_26.tar
/etc/gitlab/
/etc/gitlab/gitlab.rb
/etc/gitlab/gitlab-secrets.json
/etc/gitlab/trusted-certs/
Configuration backup archive complete:
/etc/gitlab/config_backup/gitlab_config_1627267534_2021_07_26.tar
Keeping all older configuration backups
[root@ubuntu1804 ~]#ls /etc/gitlab/config_backup/
gitlab_config_1627267534_2021_07_26.tar
[root@ubuntu1804 ~]#tar tvf
/etc/gitlab/config_backup/gitlab_config_1627267534_2021_07_26.tar
tar: Removing leading `/' from member names
drwxrwxr-x root/root         02021-07-2610:45 /etc/gitlab/
-rw------- root/root    1218572021-07-2609:36 /etc/gitlab/gitlab.rb
-rw------- root/root     190212021-07-2609:40 /etc/gitlab/gitlab-secrets.json
drwxr-xr-x root/root         02021-07-2609:37 /etc/gitlab/trusted-certs/

3.6.2 手动备份数据

不同版本的备份数据命令

#GitLab 12.2之后版本
gitlab-backup create
#GitLab 12.1之前版本
gitlab-rake gitlab:backup:create

备份相关配置

#默认在/etc/gitlab/gitlab.rb文件中指定备份路径,如果目录空间不足,可以修改新的目录
#注意:修改完配置需要执行gitlab-ctl reconfigure
# gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"
#备份的文件权限,所有者和所属组为git
# gitlab_rails['backup_archive_permissions'] = 0644
#默认备份过期时长为7天,单位为s, 之后会被自动删除
# gitlab_rails['backup_keep_time'] = 604800

范例:新版备份

[root@ubuntu1804 ~]#gitlab-backup create
2021-07-2611:02:32 +0800-- Dumping database ...
Dumping PostgreSQL database gitlabhq_production ... [DONE]
2021-07-2611:02:35 +0800--done
2021-07-2611:02:35 +0800-- Dumping repositories ...
 * gitlab-instance-d0dfe28d/Monitoring
(@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b)
...
 * gitlab-instance-d0dfe28d/Monitoring
(@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b)
... [EMPTY] [SKIPPED]
 * gitlab-instance-d0dfe28d/Monitoring.wiki
(@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.
wiki) ...
 * gitlab-instance-d0dfe28d/Monitoring.wiki
(@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.
wiki) ... [EMPTY] [SKIPPED]
 * gitlab-instance-d0dfe28d/Monitoring.design
(@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.
design) ...
 * gitlab-instance-d0dfe28d/Monitoring.design
(@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.
design) ... [EMPTY] [SKIPPED]
 * testgroup/testproject
(@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35)
...
 * testgroup/testproject
(@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35)
... [DONE]
 * testgroup/testproject.wiki
(@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.
wiki) ...
 * testgroup/testproject.wiki
(@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.
wiki) ... [EMPTY] [SKIPPED]
 * testgroup/testproject.design
(@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.
design) ...
 * testgroup/testproject.design
(@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.
design) ... [EMPTY] [SKIPPED]
2021-07-2611:02:35 +0800--done
2021-07-2611:02:35 +0800-- Dumping uploads ...
2021-07-2611:02:35 +0800--done
2021-07-2611:02:35 +0800-- Dumping builds ...
2021-07-2611:02:35 +0800--done
2021-07-2611:02:35 +0800-- Dumping artifacts ...
2021-07-2611:02:35 +0800--done
2021-07-2611:02:35 +0800-- Dumping pages ...
2021-07-2611:02:35 +0800--done
2021-07-2611:02:35 +0800-- Dumping lfs objects ...
2021-07-2611:02:35 +0800--done
2021-07-2611:02:35 +0800-- Dumping container registry images ...
2021-07-2611:02:35 +0800-- [DISABLED]
Creating backup archive: 1627268555_2021_07_26_14.1.0_gitlab_backup.tar ... done
Uploading backup archive to remote storage  ... skipped
Deleting tmp directories ... done
done
done
done
done
done
done
done
Deleting old backups ... skipping
Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data
and are not included in this backup. You will need these files to restore a
backup.
Please back them up manually.
Backup task is done.
#默认备份保存在下面目录
[root@ubuntu1804 ~]#ll /var/opt/gitlab/backups/
-rw-------1gitgit307200 Jul 2611:02
1627268555_2021_07_26_14.1.0_gitlab_backup.tar

范例: 旧版备份数据

#在任意目录即可备份当前gitlab数据
[root@ubuntu1804 ~]#gitlab-rake gitlab:backup:create
2020-03-0714:34:56 +0800-- Dumping database ...
Dumping PostgreSQL database gitlabhq_production ... [DONE]
2020-03-0714:34:57 +0800--done
2020-03-0714:34:57 +0800-- Dumping repositories ...
 * testgroup/testproject ... [DONE]
[SKIPPED] Wiki
2020-03-0714:34:58 +0800--done
2020-03-0714:34:58 +0800-- Dumping uploads ...
2020-03-0714:34:58 +0800--done
2020-03-0714:34:58 +0800-- Dumping builds ...
2020-03-0714:34:58 +0800--done
2020-03-0714:34:58 +0800-- Dumping artifacts ...
2020-03-0714:34:58 +0800--done
2020-03-0714:34:58 +0800-- Dumping pages ...
2020-03-0714:34:58 +0800--done
2020-03-0714:34:58 +0800-- Dumping lfs objects ...
2020-03-0714:34:58 +0800--done
2020-03-0714:34:58 +0800-- Dumping container registry images ...
2020-03-0714:34:58 +0800-- [DISABLED]
Creating backup archive: 1583562898_2020_03_07_11.11.8_gitlab_backup.tar ...
done
Uploading backup archive to remote storage  ... skipped
Deleting tmp directories ... done
done
done
done
done
done
done
done
Deleting old backups ... skipping
[root@ubuntu1804 ~]#ll /var/opt/gitlab/backups/
-rw-------1gitgit102400 Mar  714:34
1583562898_2020_03_07_11.11.8_gitlab_backup.tar

2.6.4 模拟删除项目

3.6.5 执行恢复

恢复的前提条件

备份和恢复使用的版本要一致
还原相关配置文件后,执行gitlab-ctl reconfigure
确保gitlab正在运行状态

新版恢复方法

#恢复前先停止两个服务
[root@ubuntu1804 ~]#gitlab-ctl stop puma
[root@ubuntu1804 ~]#gitlab-ctl stop sidekiq
#恢复时指定备份文件的时间部分,不需要指定文件的全名
[root@ubuntu1804 ~]#gitlab-backup restore BACKUP=备份文件名的时间部分

# 示例

[root@ubuntu1804 ~]#gitlab-backup restore BACKUP=1583562898_2020_03_07_11.11.8
#Next, restore /etc/gitlab/gitlab-secrets.json if necessary, as previously
mentioned.Reconfigure, restart and check GitLab:
[root@ubuntu1804 ~]#gitlab-ctl reconfigure
[root@ubuntu1804 ~]#gitlab-ctl restart

# 后续检查可选做

[root@ubuntu1804 ~]#gitlab-rake gitlab:check SANITIZE=true
#In GitLab 13.1 and later, check database values can be decrypted especially if
/etc/gitlab/gitlab-secrets.json was restored, or if a different server is the
target for the restore.
[root@ubuntu1804 ~]#gitlab-rake gitlab:doctor:secrets

旧版恢复方法

#恢复前先停止两个服务
[root@ubuntu1804 ~]#gitlab-ctl stop unicorn
[root@ubuntu1804 ~]#gitlab-ctl stop sidekiq
  • # 恢复时指定备份文件的时间部分,不需要指定文件的全名
[root@ubuntu1804 ~]# gitlab-rake gitlab:backup:restore BACKUP=备份文件名的时间部分

范例:新版恢复过程

[root@ubuntu1804 ~]#gitlab-ctl stop puma
[root@ubuntu1804 ~]#gitlab-ctl stop sidekiq
[root@ubuntu1804 ~]#gitlab-ctl status
run: alertmanager: (pid 886) 486s; run: log: (pid 863) 486s
run: gitaly: (pid 916) 485s; run: log: (pid 872) 486s
run: gitlab-exporter: (pid 888) 486s; run: log: (pid 857) 486s
run: gitlab-workhorse: (pid 909) 485s; run: log: (pid 865) 486s
run: grafana: (pid 908) 485s; run: log: (pid 871) 486s
run: logrotate: (pid 910) 485s; run: log: (pid 864) 486s
run: nginx: (pid 905) 485s; run: log: (pid 884) 486s
run: node-exporter: (pid 885) 486s; run: log: (pid 882) 486s
run: postgres-exporter: (pid 906) 485s; run: log: (pid 880) 486s
run: postgresql: (pid 917) 485s; run: log: (pid 878) 486s
run: prometheus: (pid 887) 486s; run: log: (pid 858) 486s
down: puma: 386s, normally up; run: log: (pid 879) 486s
run: redis: (pid 915) 485s; run: log: (pid 883) 486s
run: redis-exporter: (pid 907) 485s; run: log: (pid 870) 486s
down: sidekiq: 379s, normally up; run: log: (pid 881) 486s
#确保备份的版本名称
[root@ubuntu1804 ~]#ll
/var/opt/gitlab/backups/1627268555_2021_07_26_14.1.0_gitlab_backup.tar
-rw-------1gitgit307200 Jul 2611:02
/var/opt/gitlab/backups/1627268555_2021_07_26_14.1.0_gitlab_backup.tar
#注意:备份文件所有目录及权限属性,无需指定完整文件名
[root@ubuntu1804 ~]#gitlab-backup restore BACKUP=1627268555_2021_07_26_14.1.0
[root@ubuntu1804 ~]#gitlab-ctl reconfigure
[root@ubuntu1804 ~]#gitlab-ctl restart
ok: run: alertmanager: (pid 1853) 1s
ok: run: gitaly: (pid 1861) 1s
ok: run: gitlab-exporter: (pid 1883) 0s
ok: run: gitlab-workhorse: (pid 1885) 0s
ok: run: grafana: (pid 1893) 1s
ok: run: logrotate: (pid 1903) 0s
ok: run: nginx: (pid 1909) 1s
ok: run: node-exporter: (pid 1991) 0s
ok: run: postgres-exporter: (pid 1997) 0s
ok: run: postgresql: (pid 2006) 0s
ok: run: prometheus: (pid 2015) 1s
ok: run: puma: (pid 2023) 0s
ok: run: redis: (pid 2029) 1s
ok: run: redis-exporter: (pid 2035) 0s
ok: run: sidekiq: (pid 2041) 0s
#观察日志,等待恢复完成,需要再等一会儿再验证是否恢复
[root@ubuntu1804 ~]#gitlab-ctl  tail

范例:旧版恢复过程

确认恢复数据:

恢复后再将之前停止的两个服务启动

[root@ubuntu1804 ~]# gitlab-ctl start sidekiq
ok: run: sidekiq: (pid 16859) 0s
[root@ubuntu1804 ~]# gitlab-ctl start unicorn
ok: run: unicorn: (pid 16882) 1s
#或者执行下面也可以
[root@ubuntu1804 ~]# gitlab-ctl restart

3.6.6 确保还原完成

恢复后,项目及用户信息都已还原

注意:可能需要等一段时间才能打开浏览器进行访问

3.7 GitLab 汉化

gitlab 默认是英文界面,可以汉化为中文界面,有三种汉化方式

3.7.1 官方内置的配置实现汉化

GitLab 自带中文语言支持,但汉化的不彻底,可以通过下面配置修改语言显示

查看效果

3.7.2 第三方汉化包

基于第三方开发爱好者实现,通过GitLab 中文社区版进行汉化,此项目更新较慢,只支持特定的较老版本当前只支持12.2版本

注意: 选择相同的版本才能汉化

汉化包地址:

https://gitlab.com/xhang/gitlab

下载对应版本的语言包替换

https://gitlab.com/xhang/gitlab/-/archive/v12.3.5-zh/gitlab-v12.3.5-zh.tar
https://gitlab.com/xhang/gitlab/-/archive/v11.11.5-zh/gitlab-v11.11.5-zh.tar
https://gitlab.com/xhang/gitlab/-/archive/v11.9.8-zh/gitlab-v11.9.8-zh.tar
3.7.2.1 通过第三方汉化包直接替换实现
  • # gitlab-ctl stop
# wget https://gitlab.com/xhang/gitlab/-/archive/v12.3.5-zh/gitlab-v12.3.5-
zh.tar
  • # tar xvf gitlab-vX.Y.Z-zh.tar

  • # cp -rp /opt/gitlab/embedded/service/gitlab-rails /opt/gitlab-rails.bak # 备份源文件

  • # cp -rf gitlab-vX.Y.Z-zh/* /opt/gitlab/embedded/service/gitlab-rails/ # 替换文件

  • # gitlab-ctl reconfigure

# gitlab-ctl start

Web 界面更改语言:

右上角的账户下拉框选Settings然后左侧Preferences设置项,然后语言选择中文

保存后刷新界面

3.7.2.2 通过第三方汉化包对比进行汉化

本方式汉化效果比上面方式更好,推荐使用

# cd ~
  • # git clone https://gitlab.com/xhang/gitlab.git

  • # head -1 /opt/gitlab/version-manifest.txt # 查看当前 gitlab 版本

  • # gitlab_version=$(cat /opt/gitlab/embedded/service/gitlab-rails/VERSION)

  • # cd gitlab

  • # git diff v${gitlab_version} v${gitlab_version}-zh > /root/${gitlab_version}zh.diff

  • # gitlab-ctl stop

  • # patch -f -d /opt/gitlab/embedded/service/gitlab-rails -p1 <

/root/${gitlab_version}-zh.diff
  • # gitlab-ctl reconfigure

  • # gitlab-ctl start

  • # gitlab-ctl status

Web 界面更改语言:

右上角的账户下拉框选Settings然后左侧Preferences设置项,然后语言选择中文

3.8 GitLab 迁移和升级

在生产中升级往往伴随着服务器的迁移,比如从本地机房迁移到云环境中,而实现升级

迁移流程

  • 在原GitLab主机上备份配置文件和数据

  • 在目标主机上安装相同的版本的GitLab软件

  • 还原配置和数据

  • 本质上就是备份和恢复的过程

升级流程

  • 如果新主机,需要先安装原版本,并还原配置和数据

  • 不能直接跳过中间的版本直接升级,选择最近的大版本进行升级

  • 比如:12.1想升级到13.0,先升级到12.X最高版,再升级到13.0.

  • 下载新版本的安装包,直接安装包

安装包时可能会提示出错,原因是版本升级后有些配置项会过时,根据提示修改配置即可

重新配置: gitlab-ctl reconfigure

重启服务: gitlab-ctl restart

3.9 实现 Https

GitLab 如果用于不安全的网络,建议使用 https

官方说明

https://docs.gitlab.com/omnibus/settings/nginx.html#enable-https

范例:

#创建证书
[root@gitlab ~]# mkdir -p /etc/gitlab/ssl; cd /etc/gitlab/ssl
[root@gitlab ssl]#openssl genrsa -out gitlab.wang.org.key 2048
[root@gitlab ssl]#openssl req -days 3650 -x509 \
-sha256-nodes-newkey rsa:2048 -keyout gitlab.wang.org.key -out
gitlab.wang.org.crt
#修改配置文件
[root@gitlab ~]# vim /etc/gitlab/gitlab.rb
external_url "https://gitlab.example.com"#此项必须修改为https
nginx['enable'] =true
nginx['client_max_body_size'] ='1000m'
nginx['redirect_http_to_https'] =true
nginx['redirect_http_to_https_port'] =80# 所有请求80的都跳转到443
nginx['ssl_certificate'] ="/etc/gitlab/ssl/gitlab.wang.org.crt"
nginx['ssl_certificate_key'] ="/etc/gitlab/ssl/gitlab.wang.org.key"
nginx['ssl_ciphers'] ="ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
nginx['ssl_prefer_server_ciphers'] ="on"
nginx['ssl_protocols'] ="TLSv1.2"
nginx['ssl_session_cache'] ="shared:SSL:10m"
nginx['ssl_session_timeout'] ="1440m"
#重新初始化
[root@gitlab ~]# gitlab-ctl reconfigure
[root@gitlab ~]# gitlab-ctl status
#还登录原来的URL,会自动跳转到 https

3.10 找回 GitLab 忘记的密码

官方说明

https://docs.gitlab.com/ee/security/reset_user_password.html#reset-the-root-
password

范例:

[root@gitlab ~]#gitlab-rails console -e production
#此步可能比较慢,需要等一段时间
--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
 GitLab:       15.1.2 (ea7455c8292) FOSS
 GitLab Shell: 14.7.4
 PostgreSQL:   13.6
------------------------------------------------------------[ booted in23.59s ]
Loading production environment (Rails 6.1.4.7)
#输入下面指令
irb(main):001:0> user = User.where(id: 1).first
#更改密码并确认密码
irb(main):002:0> user.password="87654321"
irb(main):003:0> user.password_confirmation="87654321"
#保存
irb(main):004:0> user.save
#退出控制台
irb(main):005:0> quit
#验证用新密码登录

4 常见面试题

简述下软件交付过程? 简述什么是版本控制系统(VCS)? 简述什么是 DevOps?