一、DevOps 介绍
1、什么是 DevOps
DevOps 即开发 Development 和 Operations运维的缩写。
DevOps的维基百科定义是这样的:
DevOps是一组过程、方法与系统的统称,用于促进开发、技术运营和质量保障(QA)部门之间的沟
通、协作与整合。
2、DevOps 相关的软件
DevOps 有多个不同的阶段:计划,构建,持续集成,部署,运维,持续反馈
DevOps 涉及的四大相关平台
项目管理:如:Jira,禅道
代码托管:如:Gitlab,SVN
持续交付:如:Jenkins,Gitlab
运维平台:如:腾讯蓝鲸,Spug等
3、持续集成、持续交付和持续部署 CICD
CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。CI/CD 的核心概念是持续 集成、持续交付和持续部署。作为一个面向开发和运营团队的解决方案,CI/CD 主要针对在集成新代码 时所引发的问题
1.持续集成
集成指将多位开发者的开发代码提交后,合并集成在一起,存放在代码库的过程,并且后续还会不断的迭代更新代码
持续集成是指多名开发者在开发不同功能代码的过程当中,可以频繁的将代码行合并到一起并切相互不 影响工作。很多情况下每天都要进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。
CI属于开发人员的自动化流程。成功的 CI 意味着应用代码的新更改会定期构建、测试并合并到共享存储 库中。该解决方案可以解决在一次开发中有太多应用分支,从而导致相互冲突的问题。
持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。
2.持续交付
完成 CI 中构建及单元测试和集成测试的自动化流程后,持续交付可以自动的将已验证的代码发布到存储 库。为了实现高效的持续交付流程,务必要确保 CI 已内置于开发管道。持续交付的目标是拥有一个可随 时部署到生产环境的代码库。
在持续交付中,每个阶段(从代码更改的合并,到生产就绪型构建版本的交付)都涉及测试自动化和代 码发布自动化。在流程结束时,运维团队可以快速、轻松地将应用部署到生产环境中。
3.持续部署
最后的阶段是持续部署。作为持续交付(自动将生产就绪型构建版本发 布到代码存储库)的进一步延伸,持续部署可以自动将应用发布到生产环境。由于在生产之前的管道阶段 没有手动风控,因此持续部署在很大程度上都得依赖精心设计的测试自动化。
4、CICD 流程过程和架构
1.CICD流程
编写代码 -》 代码仓库 -》 Clone代码 -》 代码质量检测 -》 编译或打包 -》 代码分发 -》 服务器下线 -》 停止服务 -》 代码替换 -》 启动服务 -》 服务检测 -》 服务器上线 -》 用户访问
开发人员不断的进行代码提交到本地,再提交到运程的代码仓库服务器
Jenkins作为持续集成工具,使用Git工具到Git仓库拉取代码到集成服务器,代码测试与审查,再配 合JDK,Maven,Go等软件完成代码编译,测试,打包等工作,在这个过程中每一步如果出错,都 需要重新再执行一次整个流程。
Jenkins把生成的软件jar或war包等分发到测试服务器或者生产服务器,测试人员或用户就可以访问 应用。
2.CICD 基础架构
代码仓库服务器
持续集成服务器
测试服务器
生产服务器
3.版本控制系统 VCS
1 关于版本控制
版本控制(Version control)是维护工程蓝图的标准做法,能追踪工程蓝图从诞生一直到定案的过程
版本控制也是一种软件工程技巧,借此能在软件开发的过程中,确保由不同人所编辑的同一程序文件都得到同步
软件工程师常利用版本控制来跟踪、维护原始码、文档以及配置文件等的改动
2 软件版本控制的方法
最简单的情况下,软件设计师可以自己保留一个程序的许多不同版本,并且为它们做适当的编号2使用版本控制系统(Version Control System,VCS),实现部分或全部版本控制工作的自动化,版本控制系统是一种软件,可以帮助软件团队的开发人员协同工作,并存档他们工作的完整历史记录。
4.版本控制系统分类
1 本地版本(单机版)控制系统
第一代版本控制系统被称为本地版本控制系统。通过加锁将并发执行转换成顺序执行。 一次只能有一个人处理文件。
具体流程如下:首先,应该把文件放在一个服务器上,方便使用者上传或下载文件;其次,任何人想对文件修改时,需要先把这个文件加锁,通过checkout指令,使得其他人无法修改;最后,当修改完成之后,需要释放锁,通过checkin指令,形成一个新的版本,存放到服务器端。
2 集中式版本控制系统
想要完成任何提交和回滚都依赖于连接集中的代码服务器才能实现,如果无法连接至代码的服务器,比如下班回家后将无法提交代码
此外此集中式服务器还存在单点问题,在集中式实例的不可用期间,开发人员就无法推送、合并或回滚代码
此方式可以更好的实现软件仓库的安全访问限制和控制
3 分布式版本控制系统
在每个用户都有一个完整的服务器,用于保存软件的完整版本,然后再部署一个中央服务器
用户可以先将代码提交到本地,没有网络也可以先提交到本地,然后在有网络的时候再提交到中央服务器,这样就大大方便了开发者
相比集中式的版本控制系统,工作的时候需要先从中央服务器获取最新的代码,改完之后需要提交,如果是一个比较大的文件则需要足够快的网络才能快速提交完成
而使用分布式的版本控制系统,每个用户都是一个完整的版本库,即使没有中央服务器也可以提交代码或者回滚,最终再把改好的代码提交至中央服务器进行合并即可。
此方式不容易实现软件仓库的安全访问限制和控制
5.常见的版本控制系统
1 CVS(Concurrent Version System) 集中式版本控制系统
CVS是一个C/S系统,是一个早期常用的代码版本控制软件。多个开发人员通过一个中心版本控制系统来记录文件版本,从而达到保证文件同步的目的。CVS版本控制系统是一种GNU软件包,主要用于在多人开发环境下的源码的维护。
由于 CVS 是集中式版本控制系统,所以它有客户端和服务端之区分。但要开始使用 CVS 的话,即使只在你的本地机器上使用,也必须设置 CVS 的服务端。
2 SVN(Subversion) 集中式版本控制系统
SVN 依赖于网络,需要在各个开发主机上安装客户端软件,并且在一台服务器集中进行版本管理和存储.目前依然有部分公司在使用
优点:
管理方便,逻辑明确,符合一般人思维习惯。
易于管理,集中式服务器更能保证安全性。
代码一致性非常高。
适合开发人数不多的项目开发。
缺点:
服务器压力太大,数据库容量暴增。
如果不能连接到服务器上,基本上不可以工作,如果服务器不能连接上,就不能提交,还原,对比等等。
不适合开源开发(开发人数非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题。
6.Git
在本地就可以完成提交,因此不需要网络,提交完成后,可以有网络环境时,再同步到远程仓库服务器
优点:
适合分布式开发,强调个体。
公共服务器压力和数据量都不会太大。
速度快、灵活。
任意两个开发者之间可以很容易的解决冲突。
支持离线工作。
缺点:
不符合常规思维。
学习难度大,学习周期相对而言比较长。
代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息。
无力支持大型二进制文件
具有大量历史记录的超大型存储库会降低交互速度
7.常见的软件部署模式
1 蓝绿部署 Blue-green Deployments
蓝绿部署指的是不停止老版本代码(不影响上一个版本访问),而是在另外一套环境部署新版本然后进行测试,测试通过后将用户流量切到新版本,其特点为业务无中断,升级风险相对较小,但本方式成本较高。
具体过程:
1、当前版本(V1)业务正常访问
2、在另外一套环境部署新代码版本(V2),代码可能是增加了功能或者是修复了某些bug
3、测试通过之后将用户请求流量切到新版本环境
4、观察一段时间,如有异常直接切换旧版本
5、下次升级,将旧版本(V2)升级到新版本(V3)
蓝绿部署适用的场景:
1、不停止老版本,额外部署一套新版本,等测试确认新版本正常后,才将用户请求切换至新版本,如果有问题,切换回老版本
2、蓝绿发布是一种用于升级与更新的发布策略,部署的最小维度是容器,而发布的最小维度是应用。
3、蓝绿发布对于增量升级有比较好的支持,但是对于涉及数据表结构变更等等不可逆转的升级,并不完全合适用蓝绿发布来实现,需要结合一些业务的逻辑以及数据迁移与回滚的策略才可以完全满足需求。
2 金丝雀(灰度)发布 Canary Deployment
金丝雀发布也叫灰度发布,是指在黑与白之间,能够平滑过渡的一种发布方式,灰度发布是增量发布(例如:2%、25%、75%、100%)进行更新)的一种类型,灰度发布是在原有版本可用的情况下,同时部署一个新版本应用作为“金丝雀”(小白鼠),测试新版本的性能和表现,以保障整体系统稳定的情况下,尽早发现、调整问题。因此,灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
金丝雀/灰度发布步骤组成:
1、准备好部署各个阶段的工件,包括:构建组件,测试脚本,配置文件和部署清单文件。
2、从负载均衡列表中移除掉“金丝雀”服务器(选择全部服务器中的一部分)。
3、升级“金丝雀”应用(排掉原有流量并进行部署)。
4、对应用进行自动化测试。
5、将“金丝雀”服务器重新添加到负载均衡列表中(连通性和健康检查)。
6、如果“金丝雀”在线使用测试成功,升级剩余的其他服务器。否则就回滚回旧版本。
金丝雀/灰度发布部署适用的场景:
1、不停止老版本,额外搞一套新版本,不同版本应用共存。
2、灰度发布中,常常按照用户设置路由权重,例如90%的用户维持使用老版本,10%的用户尝鲜新版本。
3、经常与A/B测试一起使用,用于测试选择多种方案。
3 滚动发布(更新)
滚动发布即逐步升级服务中的节点
滚动发布是指每次只升级一个或多个服务实例,升级完成后加入生产环境,不断执行这个过程,直到集群中的全部旧版本升级新版本。
滚动发布过程
1. 先升级1个服务实例,主要做部署验证
2. 每次升级1个服务实例,自动从LB上摘掉,升级成功后自动加入集群
3. 事先需要有自动更新策略,分为若干次,每次数量/百分比可配置
4. 回滚是发布的逆过程,先从LB摘掉新版本,再升级老版本,这个过程一般时间比较长
5. 自动化要求高
4 A/B测试 A/B Testing
A/B测试即同时对外提供两个APP运行环境,这和蓝绿部署的同时只有一个版本在线是不同的
A/B 测试是用来测试应用功能表现的方法,例如可用性、受欢迎程度、可见性等等
蓝绿部署和A/B测试是不同的,蓝绿部署的目的是安全稳定地发布新版本应用,并在必要时回滚
即蓝绿部署是同一时间只有一套正式环境在线,而A/B测试是两套正式环境同时在线,一般用于多个产品竟争时使用
5、版本控制系统 Git
1.数据保存方式
1 SVN 与 CVS
每次提交的文件都单独保存, 即按照文件的提交时间区分不同的版本, 保存至不同的逻辑存储区域,后期恢复时候直接基于之前版本恢复。 将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异 (它们通常称作基于差异(delta-based) 的版本控制)
2 Git
在 Git中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流。
3 git和SVN区别
git是分布式的,svn是集中式的
git是每个历史版本都存储完整的文件,便于恢复,svn是存储差异文件
git可离线完成大部分操作,svn则不能
git有着更优雅的分支和合并实现
git有着更强的撤销修改和修改历史版本的能力
git速度更快,效率更高
2.Git 相关概念和原理
Git 的数据存储从物理上分为当前项目目录和当前项目目录下的隐藏子目录.git,分别称为工作区和版本库
Git 版本库逻辑上又分为暂存区和本地仓库
1 工作区 Workspace
工作区是你当前正在编辑和修改文件的地方。它是你的项目目录 ,通常是对应于<项目目录>
在这里你可以添加、修改或删除文件。工作区中的文件可以是已被Git跟踪的文件,也可以是未被跟踪的文件。
工作区中的文件的变更不受Git的跟踪和管理,无法实现版本回滚等功能
需要将工作的的变更,通过 git add 命令加入暂存区后,才可纳入Git 的版本管理控制的范畴
2 暂存区 Staging Area/Index/Cached
也称为索引区,缓存区,用于存储在工作区中对代码进行修改后的文件所保存的地方,只有放入此区 的文件才能被git进行管理,使用 git add添加,对应为<项目目录>/.git/index文件
暂存区主要用于临时保存文件少量变更,类似于邮件中的草稿箱
当变更累积到一定阶段,希望生成里程碑式的结果时,会使用commit,将暂存区的变更一次性的 批量提交到本地仓库
3 本地仓库 Local Repository
用于存储在工作区和暂存区中改过并提交的文件地方,使用 git commit 提交,对应于/<项目目录 >/.git/
每一次commit 会生成一个唯一的ID,通常用于表示一个阶段性的新的版本
checkout命令执行了同commit命令相反的操作,它将版本中存储的commit所代表着的某个版本 恢复至工作区中
checkout命令完成后,工作区中的文件内容与其检出的提交那一刻的状态相同
若工作区中存储此前未被提交的新文件,这些文件的未被提交的新的更改会被存储仓库的旧内容覆盖
当然,用户也可以暂存这些新文件,并将带有新文件的工作区提交到版本库中,这将是新的暂存和 提交循环
4 远程仓库 Remote Repository
多个开发人员共同协作提交代码的仓库,即私有 gitlab 服务器或公有云github,gitee网站等 利用远程仓库,可以实现异地备份和远程协作
3.Git 文件的状态变化周期
文件状态变化
untracked: 在工作目录下创建的新文件,这个时候本地git仓库不知道,不能对其进行版本跟踪管理
unmodified: 添加到暂存区的文件未修改,把文件从暂存区推动到本地仓库
modified: 已经添加到暂存区的文件,在本地工作区的文件被修改了 ,需要重新添加至暂存区
staged: 文件添加到了暂存区
unstaged: 已被跟踪的工作区的文件发生更新,但还没有存入暂存区中
4.Git 提交历史和提交链
版本库上的commit历史组合起来会形成一个提交链
除了初始commit,每个commit都会都会有一个父commit,也可能会有多个父commit(比如:分支合并)
除了最新一次的commit,每个commit都会有一个子commit,也可能会有多个子commit(比如:创建新分支)
这个提交链上的commit还可以使用字符串进行引用
通常,Git会为默认创建的提交链上的最新一次提交创建一个基于字符串的引用master/main
而该提交链也称为版本库的一个分支(Branch),master/main 也是分支的名称标识
另外自动创建的还有一个HEAD引用,它代表提交链的“头”,表示当前工作区所关联到的提交链上的特定提交,通常是最新一次提交
基于HEAD指向的commit,还能够以相对方式引用历史中的提交,例如HEAD~表示前一个提交
git show HEAD命令可以查看HEAD当前所指向的commit的信息
5.Git 分支和标签
1 branch 分支
Git 的分支,其实本质上仅仅是指向提交对象的可变指针
Git 的默认分支名字是 master/main 。 在多次提交操作之后,你其实已经有一个指向最后那个提 交对象的 master/main 分支。 master 分支会在每次提交时自动向前移动。
Git的分支实现对文件的多个副本,可以实现多个不同用途的软件版本同时的演进,实现多个开发版本 的隔离
2 tag 标签
给某个状态打个标签用于记录当前状态,相当于里程碑性的提交
tag是git版本库的一个标记,指向某个commit的指针。为某个commit添加一个标签,从而对其完 成特殊标记,例如标记特定的版本信息
tag主要用于发布版本的管理,一个版本发布之后,可以为git打上 v1.0.1,v1.0.2 ...这样的类似的标 签。
通常,用户应该每天下班前提交代码并完成推送,以备份代码;只有待需要发一个版本时,才会基 于tag对相应commit进行标记
6.Git 开发分支流程
几种常见的分支模型
master:开发、测试和发布都在master分支上完成简单,但开发、测试和发布彼此影响,仅适用于单feature且无构建过程的场景
master/develop: 在开发分支开发,完成后合并至master分支,并删除develop分支
master 长期分支,记录发布历史
develop 短期分支,完成开发后合并至master分支
develop分支的开发不会影响到master分支的构建过程,但不利于同时开发多个feature;适用于单feature,可从master执行构建的场景
工作流程
~$ git checkout -b develop # from master
~$ git rebase master #完成开发、测试
~$ git checkout master
~$ git merge develop #发布
~$ git branch --delete develop
master/develop/feature
master和develop 都是长期分支
开发人员工作在各自的feature分支上,feature分支经过开发、模块测试后合并到develop分支
develop分支代码经过系统测试,release之后合并到master分支,release是短期分支
多个feature有利于更大规模的合作,但release独立分支中的bug修复变更与develop上的变更可能会导致冲突;因而,适用于多feature,develop在release过程中不会修改的场景
feature短期分支,保存研发人员研发过程
工作流程
git chechout -b feature #from develop,完成开发和特性测试
git checkout develop
git merge feature
git branch --delete feature #完成集成测试和发布
git checkout master
git merge develop
master/develop/feature/release
在前一分支模型的基础上,使用单独的release分支进行构建和bug修复
避免了因发布操作而阻塞了develop分支上的变更,但release分支存在的时间越长,导致develop合并冲突的可能性越大;因此,适用于多feature开发,但develop功能不受release影响的场景
release:短期分支,承载发布过程
工作流程
git chechout -b feature #from develop,完成开发和特性测试
git checkout develop
git merge feature
git branch --delete feature
git checkout -b release # from develop,完成测试、bug修复和发布
git checkout develop
git merge release #将release合并至develop
git checkout master
git merge release #将release合并至master
git branch --delete release #删除releae分支
git-flow
master 只能用来存储产品代码,不能直接工作在 master 分支上 ,而是在其他指定的、独立的特性分支中,避免直接提交改动到 master 分支上也是很多工作流程的一个共同准则
develop 是 进行任何新的开发的基础分支,develop是任何feature分支的父分支,用于汇集所有feature上的代码,并在必要时合并至master分支
develop分支上的代码来自于 feature、release 和 bugfix 分支
master分支上的代码来自于 release 和 bugfix 分支
master 和develop都是长期分支,它们会存活在项目的整个生命周期中,而各feature分支、release分支和bugfix分支均为临时分支,每次的使命完成后即被删除
7.Git 分支合并和变基
1 merge 合并
分支合并,即将多个分支合并成一个分支
利用 git merge 命令将指定的其它分支合并至当前分支
注意:先切换至需要合并的目标分支,再将其它分支合并至当前的目标分支
分支合并存在两种情形
快进式合并(Fast-Forward Merge)
被合并的分支master相对于合并的分支devel来说,自创建分支后并生成任何新的变动
被合并的分支master只需要将其分支指针指向devel分支的最新一次提交
三路合并(3-Way Merge)
两个分支各自沿着自己的演进路线分别创建了新的提交
合并时需要共同的祖先提交,以及各分支的最新一次提交进行合并
2 rebase 变基
变基 rebase 表示将当前的基础(父)提交改变为另一个提交,变基操作也能完成分支合并,相对于merge操作将一个分支上的所有变动一次性完成合并来说,rebase操作可以保留一个线性的变更历史
命令:git rebase 将指定的分支的提交合并到当前分支,并变基将指定分支的提交做为父提交,此步执行完后,还需要在切换至此处指定的分支,将当前分支进行merge合并
变基过程:
在图中的commit5和commit6对应的分支上先执行git rebase master
再执行checkout 切换回 master分支
在master分支最后执行git merge <commit5和commit6对应的分支>,完成变基和合并
8.Git 使用远程仓库
通过远程仓库,基于HTTP、SSH 及 Git 多种传输协议可以实现异地备份和远程协作
1 推送代码至远程仓库的步骤
在某个Git托管服务上注册一个账号,比如:GitHub,Gitee,GitLAB
在Git托管服务上创建一个仓库
在本地版本库上,使用git remote add 命令添加关联的远程库
git push 推送本地仓库到远程仓库,git pull 可以拉取远程仓库代码到本地现在仓库中
没有本地仓库的其它主机通过git clone 可以将远程仓库克隆到本地
2 设定远程仓库
添加: git remote add
列出: git remote -v
删除: git remote rm
重命名: git remote rename
3 克隆远程仓库
克隆: git clone
克隆到指定工作目录: git clone
4 远程协作
抓取远程仓库所有分支上的变更: git fetch
抓取远程仓库指定分支上的变更: git fetch
列出所有远程分支:git branch -r
将远程分支合并至本地分支,通常应该将存在映射关系(通常为同一个分支名称)的分支进行合并
5 拉取远程仓库上的变更
拉取并合并当前分支映射的远程分支上的变更至本地工作区:git pull
git pull 相当于如下两个命令生成的结果
git fetch
git merge
6 推送本地变更到远程仓库
推送指定的分支:git push
推送本地仓库中的所有分支:git push --all
推送本地仓库中的所有标签:git push --tag
6、Git 安装
1.yum源安装
[root@c7-git-81 ~]# yum list git --showduplicates
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: mirrors.bfsu.edu.cn
* extras: mirrors.bupt.edu.cn
* updates: mirrors.bupt.edu.cn
Available Packages
git.x86_64 1.8.3.1-23.el7_8 base
git.x86_64 1.8.3.1-24.el7_9 updates
git.x86_64 1.8.3.1-25.el7_9
[root@c7-git-81 ~]# yum -y install git
[root@c7-git-81 ~]# git version
git version 1.8.3.1
2.编译安装
[root@c7-git-81 ~]# yum -y install gcc make openssl-devel curl-devel expat-devel
[root@c7-git-81 ~]# wget https://github.com/git/git/archive/refs/tags/v2.43.0.tar.gz
[root@c7-git-81 ~]# ll -h v2.43.0.tar.gz
-rw-r--r--. 1 root root 11M Feb 17 06:14 v2.43.0.tar.gz
[root@c7-git-81 ~]# tar xf v2.43.0.tar.gz -C /usr/local/src/
[root@c7-git-81 ~]# cd /usr/local/src/git-2.43.0/
[root@c7-git-81 git-2.43.0]# cat INSTALL
[root@c7-git-81 git-2.43.0]# make -j `grep -c processor /proc/cpuinfo` prefix=/apps/git all
[root@c7-git-81 git-2.43.0]# make prefix=/apps/git install
[root@c7-git-81 git-2.43.0]# echo 'PATH=/apps/git/bin/:$PATH' >/etc/profile.d/git.sh
[root@c7-git-81 git-2.43.0]# . /etc/profile.d/git.sh
[root@c7-git-81 git-2.43.0]# git version
git version 2.43.0
7、Git 常用语法
1.Git 用法说明
git 命令常见用法
#查看git及子命令的帮助
git help <子命令> #不加<子命令>是查看git命令的帮助
git <子命令> --help #不加<子命令>是查看git命令的帮助
man git-<子命令>
git version #查看版本
git init #本地仓库初始化
git init --initial-branch=main #初始化主分支为main,默认为master,注意:此为新版用法
git init --bare #创建无工作区的祼仓库,适用于充当远程仓库,一般对应的目录以.git为后缀
git clone <repository_url> [workdir] #克隆url指定的项目的所有分支和标签对应文件到指定目录(默认为当前目录),并在本地创建此项目的git仓库,默认只显示master分支,而不晃示其它分支,但可以执行git checkout 分支,即可查看到其它分支的文件
git clone -b develop <repository_url> #克隆url指定的项目,并切换到develop分支
git clone -b tag <repository_url> #克隆url指定的项目,并切换到指定的tag
git config --global user.name "jiutingqiu" #设置当前用户的git全局用户名,和下面两项都存放在~/.gitconfig文件中
git config --global user.email "email@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 / . #添加指定文件、目录或当前目录下所有数据到暂存区
git mv file_oldname file_newname #将已经进入版本仓库的文件改名,注意:不支持在工作区没有存入暂存区的新创建的文件
git rm --cached file #只删除暂存区的文件,不删除工作区文件,相当于git add 反操作,和git
restore --staged 功能相同
git rm file #从删除工作目录和暂存区删除文件
git checkout file #从暂存区复制文件到工作目录
git restore --staged <file> #新版EXPERIMENTAL命令,撤销add到暂存区的文件回到工作区,重新成为untracked状态
git restore <file> #撤消已跟踪但尚未加入暂存区中的文件变更,撤消了工作区中文件的所有新的更改
git restore -s <commitid> <pathspec> #从某个提交中恢复文件
#示例:从前一次提交中恢复README.md文件:git restore -s HEAD~ READEME.md
#查看文件列表和内容
git ls-files #查看暂存区文件,选项-s显示mode bits, object name and stage number,-o显示untracked文件
git cat-file -p <blogid> #查看仓库对象的内容,仓库对象存放在.git/objects目录下
#查看文件变化
git diff [<path>...] #对比工作区和暂存区的区别
git diff --staged|cached [<path>...] #对比暂存区和本地仓库的前一次提交的区别
git diff --cached <commit> [<path>...] #对比暂存区与指定的提交
git diff [<commit>] [--] [<path>...] #对比工作区和指定提交的文件的区别
git diff <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 show [HEAD] #查看最近一次提交的详细信息,即查看HEAD当前所指向的commit的信息
#查看日志
git status #查看工作区的状态
git log #查看提交日志
git log --oneline #查看提交日志的简要信息,一个提交一行,只显示commit id的前七位
git log --oneline -N #查看最近N条commit日志
git log --pretty=oneline #查看提交日志的简要信息,一个提交一行,显示commit id 全部位
git log --pretty=raw #查看提交信息,包括对应的tree对象,父提交,作者等
git log --stats #查看提交的文件的统计信息
git log -p [commit_id] #查看指定提交和之前提交的变化详细信息
git log --author="<author-name-pattern>" #查看指定作者的提交
git log <file-pattern> #查看指定文件的提交
git log origin/main #查看远程仓库的日志
git reflog #查看分支或其它引用在本地仓库的完整历史记录
#回滚提交,本质上是将HEAD和master引用移到指定的commit上,是否基于指定的commit连同重置暂存区和工作区则取决于使用的选项
git reset --hard|soft|minxed HEAD^^ #git版本回滚, HEAD为当前版本,加一个^为上一个,^^为上上一个版本,也可以将^换成~
git reset --hard|soft|minxed HEAD~n #回滚前n个版本,0表示当前commit,~或者~1表示前一个commit,即相当于HEAD^
git reset --hard|soft|minxed 5ae4b06 #回退到指定id的版本,使用 git reflog 获取每次提交的ID
git reset --hard|soft|minxed v1.0 #支持tag,此处的v1.0为tag
#分支管理
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 branch -r #列出所有远程分支
#切换分支
git checkout <分支名> #切换到已有的分支,HEAD也会自动指向目标分支上的最新提交
git checkout <tag> #切换至指定标签,检出到标签,会导致分离头指针,且新创建的提交也将处于分离的状态
git checkout -b <分支名> #创建并切换到一个新分支
git checkout -b <分支名> origin/<分支名> #利用服务器远程仓库的分支,同步在本地创建分支
git checkout [<commit>]-- <file> ... #找回在工作区删除的已存入暂存区或提交的文件
git merge master -m <message> #将master分支合并至当前分支,无选项-m, 则为交互式输入信息
git merge orgin/<branch_name> #将远程分支合并到本地当前分支,通常应该将存在映射关系(通常为同一个分支名称)的分支进行合并
git merge --abort #取消合并
git switch <branchname> #切换分支.是Git 2.23 版本引入的新命令,git switch 是一个只专注于分支切换的命令,而 git checkout 则是一个历史更久,有更多的用途。除了切换分支外,git
checkout 还可以用于还原文件、切换到特定的提交、创建新的分支等更通用的命令
git switch -c <new-branch> #切抽并创建分支,相当于git branch <new-branch> && git
switch <new-branch>
#标签
git tag <tagname> #当前commit创建轻量标签
git tag <tagname> <commit_id> #将指定commit创建轻量标签
git tag -a <tagname> -m <message> #将当前commit创建附注标签
git tag -a <tagname> -m <message> <commit_id> #将指定commit创建附注标签
git tag -d <tagname> #删除标签
git reset --hard <tagname> #回滚到指定标签
git tag #查看标签
git tag -l [<pattern>] #查看指定模式的标签
git show <tagname> #查看指定标签详细信息
#远程仓库
git remote -v #查看远程仓库
git remote show <remote_name> #查看远程仓库详细信息,<remote_name>默认origin
git remote add <remote_name> <url> #创建远程仓库,<remote_name> 默认为origin
git remote add origin git@gitlab.example.com:testgroup/testproject.git #建立远程仓库和本地origin关联
git remote rename origin new-origin #修改默认远程仓库名称origin为新的名称new-origin
git remote remove|rm origin #删除远程仓库的关联
#和远程仓库推和位
git push #将本地仓库提交代码到远程服务器
git push <remote_name> <branch_name> #推送指定分支到指定的远程仓库
git push origin master #将当前分支推送到远程的 master 分支
git push origin dev #将当前分支推送到远程的dev分支,如果远程没有dev会自动创建
git push -u|--set-upstream origin master #将本地master分支推送到远程仓库master,-u表示以后可用git push 代替此命令
git push origin main:dev #将本地main分支推送至远程dev分支
git push origin :dev #将空分支推送到远程dev,即删除远程dev分支
git push <remote_name> --all #推送本地仓库的的所有有分支到远程
git push -u origin --all #推送所有分支
git push origin <tagname> #推送本地仓库指定的tag到远程
git push origin --tag <tagname> #推送本地仓库指定的tag到远程
git push <remote_name> --tags #将本地仓库所有的tag都推送到远程,默认不会推送标签
git push --delete origin <tagname> #删除远程仓库的标签
git pull #从远程服务器获取所有分支的代码到本地仓库,并自动合并到本地仓库和工作区
git pull <remote_name> #拉取并合并远程分支变更到当前分支,相当于git fetch <remote_name> 和git merge <remote_name>
git pull origin dev #从远程服务器指定的分支dev拉取代码到本地仓库,并自动合并到本地仓库和工作区
git fetch <remote_name> #获取远程仓库所有分支上的变更
git fetch <remote_name> <branch_name> #获取远程仓库指定分支上的变更,但不合并
git fetch origin master #从远程仓库origin的master分支获取最新版本到本地仓库,但不合并至工作区,需要手动完成合并
#忽略文件,实现不跟踪指定文件
vim .gitignore #定义忽略文件,即不放在仓库的文件
2.Git练习
1 创造项目并初始化配置
[root@c7-git-81 ~]# mkdir -pv /data/myapp
mkdir: created directory ‘/data’
mkdir: created directory ‘/data/myapp’
[root@c7-git-81 ~]# cd /data/myapp/
[root@c7-git-81 myapp]# git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /data/myapp/.git/
[root@c7-git-81 myapp]# ls -a
. .. .git
[root@c7-git-81 myapp]# tree .git
.git
├── branches #分支
├── config #git config命令设置的配置信息
├── description #被git web(Github的原型)用来显示对仓库的描述
├── HEAD #当前分支的标识符号,一般指向refs/heads目录下的分支文件
├── hooks #触发器规则的文件,俗称"钩子文件"
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── push-to-checkout.sample
│ ├── sendemail-validate.sample
│ └── update.sample
├── info #一些特殊文件设置目录,比如忽略文件设置,.gitignore是互补的
│ └── exclude
├── objects #存放git对象,git 核心的文件目录
│ ├── info
│ └── pack
└── refs #各个提交对象的标识(SHA-1)文件
├── heads #分支相关信息的目录
└── tags #标签相关信息的目录
9 directories, 18 files
#设置git,提交commit之前需要先配置git的基本信息
#选项--system 表示针对所有用户的配置,保存在/etc/gitconfig文件中
#选项--global 表示当前用户环境,保存在~/.gitconfig文件中,推荐使用
#选项--local 表示只针对当前目录(项目)的配置,保存在当前目录的.git/config文件中,此为默认值,可省略
#优先级:local > global > system
#配置文件使用ini格式,存在一至多个[section],各配置参数可以section为前缀引用
#列出已有配置:git config -l | --list
#用户名,另外还可以使用author.name标记作者,以及使用committer.name标记提交者
[root@c7-git-81 myapp]# git config --global user.name jiutingqiu
#用户的邮箱,还可以使用author.email标记作者邮箱和使用committer.email标记提交者邮箱
[root@c7-git-81 myapp]# git config --global user.email jiutingqiu@163.com
#为color.diff和color.grep设定默认值,true或auto表示启用语法着色功能,false或never表示关闭语法着色功能
[root@c7-git-81 myapp]# git config --global color.ui true
#配置git默认使用的文本编辑器,也可由环境变量GIT_EDITOR指定,且此变量的优先级更高
[root@c7-git-81 myapp]# git config --global core.editor vim
#system级和global优先级比较
[root@c7-git-81 ~]# git config --system user.name jtq
[root@c7-git-81 ~]# git config --system user.name jtq
[root@c7-git-81 ~]# git config -l
user.name=jtq
user.name=jiutingqiu
user.email=jiutingqiu@163.com
core.editor=vim
[root@c7-git-81 ~]# cd /data/myapp/
[root@c7-git-81 myapp]# git config -l
user.name=jtq
user.name=jiutingqiu
user.email=jiutingqiu@163.com
core.editor=vim
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
#只显示global
[root@c7-git-81 myapp]# git config -l --global
user.name=jiutingqiu
user.email=jiutingqiu@163.com
core.editor=vim
#删除配置
[root@c7-git-81 myapp]# git config --unset --system user.name jtq
[root@c7-git-81 myapp]# git config -l
user.name=jiutingqiu
user.email=jiutingqiu@163.com
core.editor=vim
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
错误
[root@c7-git-81 ~]# git config --system user.name jtq
error: could not lock config file /apps/git/etc/gitconfig: No such file or directory
[root@c7-git-81 ~]# mkdir /apps/git/etc
[root@c7-git-81 ~]# touch /apps/git/etc/gitconfig
2 添加暂存区并提交数据
[root@c7-git-81 myapp]# echo test v1.0 >a.txt
[root@c7-git-81 myapp]# git add a.txt
[root@c7-git-81 myapp]# git commit -m 'a.txt v1.0'
[master (root-commit) 8d864e1] a.txt v1.0
1 file changed, 1 insertion(+)
create mode 100644 a.txt
3 设置忽略文件
配置.gitignore文件让 Git 不再管理当前目录下的某些文件。 生产中有如下几类文件可能需要忽略
程序运行时产生的临时文件
程序连接数据库这一类的配置文件
程序本地开发使用的图片文件
其它不想被共享的文件
[root@c7-git-81 myapp]# cat .gitignore
/bin
/target
.classpath
.project
.settings
*.h
!test.h
*.py[c|x]
无须提交此文件.gitignore 就可以立即生效忽略,但为了保存此文件,还是最终需要提交此文件到本地仓库中
[root@c7-git-81 myapp]# git add .gitignore
[root@c7-git-81 myapp]# git commit -m '设置忽略'
[master b5639c6] 设置忽略
1 file changed, 8 insertions(+)
create mode 100644 .gitignore
4 将文件加入暂存区再取消添加
[root@c7-git-81 myapp]# touch f1.txt
[root@c7-git-81 myapp]# 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@c7-git-81 myapp]# git add f1.txt
#查看暂存区文件
[root@c7-git-81 myapp]# git ls-files
f1.txt
#从暂存区删除
#方法1
[root@c7-git-81 myapp]# git rm --cached f1.txt
rm 'f1.txt'
#方法2
[root@c7-git-81 myapp]# git restore --staged f1.txt
5 查看暂存区的文件内容
[root@c7-git-81 myapp]# echo testdata > test.txt
[root@c7-git-81 myapp]# git add .
[root@c7-git-81 myapp]# git ls-files -s
100644 5246f6e1c1aae9782c6582af6ca9c3fe3e6084a6 0 a.txt
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 f1.txt
100644 d383c56fffdc91c1615a9b26c3fb87c73a565989 0 test.txt
[root@c7-git-81 myapp]# git cat-file -t d383c56fffdc91c1615a9b26c3fb87c73a565989
blob
[root@c7-git-81 myapp]# git cat-file -p d383c56fffdc91c1615a9b26c3fb87c73a565989
testdata
6 利用暂存区恢复误删除的工作区文件
[root@c7-git-81 myapp]# git ls-files
[root@c7-git-81 myapp]# touch a1.txt
[root@c7-git-81 myapp]# git add .
[root@c7-git-81 myapp]# git ls-files
a.txt
a1.txt
f1.txt
test.txt
[root@c7-git-81 myapp]# rm -f a1.txt
[root@c7-git-81 myapp]# ls
a.txt f1.txt test.txt
[root@c7-git-81 myapp]# git checkout a1.txt
Updated 1 path from the index
[root@c7-git-81 myapp]# ls
a1.txt a.txt f1.txt test.txt
7 同时删除工作区和暂存区
[root@c7-git-81 myapp]# touch f2.txt
[root@c7-git-81 myapp]# git add .
[root@c7-git-81 myapp]# git ls-files
a.txt
a1.txt
f1.txt
f2.txt
test.txt
[root@c7-git-81 myapp]# ls
a1.txt a.txt f1.txt f2.txt test.txt
[root@c7-git-81 myapp]# git rm -f f2.txt
rm 'f2.txt'
[root@c7-git-81 myapp]# ls
a1.txt a.txt f1.txt test.txt
[root@c7-git-81 myapp]# git ls-files
a.txt
a1.txt
f1.txt
test.txt
8 回滚工作区的文件为暂存区中版本
[root@c7-git-81 myapp]# echo v1 >f1.txt
[root@c7-git-81 myapp]# git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: a.txt
deleted: f1.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
f1.txt
[root@c7-git-81 myapp]# git add .
[root@c7-git-81 myapp]# echo v2 > f1.txt
[root@c7-git-81 myapp]# git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: a.txt
modified: f1.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: f1.txt
[root@c7-git-81 myapp]# git checkout -- f1.txt
[root@c7-git-81 myapp]# cat f1.txt
v1
9 多次提交后回滚至指定提交的版本
git reset 是对本地仓库的项目进行回滚操作的命令,它主要有如下三个参数
--soft #工作目录和暂存区都不会被改变,只是本地仓库中的文件回滚到指定的版本,仅移动HEAD和master指针的指向,不会重置暂存区或工作区
--mixed #默认选项。回滚暂存区和本地仓库,但工作目录不受影响
--hard #本地仓库,暂存区和工作目录都回滚到指定的提交,该选项非常危险
hard
[root@c7-git-81 myapp]# echo v1 > a.txt
[root@c7-git-81 myapp]# git add a.txt
[root@c7-git-81 myapp]# git commit -m 'a v1'
[master 312f1c9] a v1
1 file changed, 1 insertion(+)
create mode 100644 a.txt
[root@c7-git-81 myapp]# git status
On branch master
nothing to commit, working tree clean
[root@c7-git-81 myapp]# echo v2 > a.txt
[root@c7-git-81 myapp]# git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: a.txt
no changes added to commit (use "git add" and/or "git commit -a")
[root@c7-git-81 myapp]# git add a.txt
[root@c7-git-81 myapp]# git commit -m 'a v2'
[master 5907af4] a v2
1 file changed, 1 insertion(+), 1 deletion(-)
[root@c7-git-81 myapp]# cat a.txt
v2
[root@c7-git-81 myapp]# git log
commit 5907af4a05025fd55bce42de467e7076a3524ed0 (HEAD -> master)
Author: jiutingqiu <jiutingqiu@163.com>
Date: Sat Feb 17 19:40:24 2024 -0800
a v2
commit 312f1c946ec55f97ee8cba93af545a6ee3e8b573
Author: jiutingqiu <jiutingqiu@163.com>
Date: Sat Feb 17 19:39:23 2024 -0800
a v1
[root@c7-git-81 myapp]# git reset --hard HEAD^
HEAD is now at 312f1c9 a v1
[root@c7-git-81 myapp]# cat a.txt
v1
[root@c7-git-81 myapp]# git log
commit 312f1c946ec55f97ee8cba93af545a6ee3e8b573 (HEAD -> master)
Author: jiutingqiu <jiutingqiu@163.com>
Date: Sat Feb 17 19:39:23 2024 -0800
a v1
#回滚到指定版本
[root@c7-git-81 myapp]# echo v2 > a.txt
[root@c7-git-81 myapp]# git add a.txt
[root@c7-git-81 myapp]# git commit -m 'a v2'
[master 42e0934] a v2
1 file changed, 1 insertion(+), 1 deletion(-)
[root@c7-git-81 myapp]# echo v3 > a.txt
[root@c7-git-81 myapp]# git add a.txt
[root@c7-git-81 myapp]# git commit -m 'a v3'
[master 609f4c3] a v3
1 file changed, 1 insertion(+), 1 deletion(-)
[root@c7-git-81 myapp]# git log
commit 609f4c3a3bdea6d3952ba815cff9322e782c8ab3 (HEAD -> master)
Author: jiutingqiu <jiutingqiu@163.com>
Date: Sat Feb 17 19:46:03 2024 -0800
a v3
commit 42e0934e0ef580187851216aac4616df15d6ff72
Author: jiutingqiu <jiutingqiu@163.com>
Date: Sat Feb 17 19:45:42 2024 -0800
a v2
commit 312f1c946ec55f97ee8cba93af545a6ee3e8b573
Author: jiutingqiu <jiutingqiu@163.com>
Date: Sat Feb 17 19:39:23 2024 -0800
a v1
[root@c7-git-81 myapp]# git reset --hard 312f1c
HEAD is now at 312f1c9 a v1
[root@c7-git-81 myapp]# cat a.txt
v1
#无法查看到被回退前的历史版本
[root@c7-git-81 myapp]# git log
commit 312f1c946ec55f97ee8cba93af545a6ee3e8b573 (HEAD -> master)
Author: jiutingqiu <jiutingqiu@163.com>
Date: Sat Feb 17 19:39:23 2024 -0800
a v1
#查看到被回退前的历史版本
[root@c7-git-81 myapp]# git reflog
312f1c9 (HEAD -> master) HEAD@{0}: reset: moving to 312f1c
609f4c3 HEAD@{1}: commit: a v3
42e0934 HEAD@{2}: commit: a v2
312f1c9 (HEAD -> master) HEAD@{3}: reset: moving to HEAD^
5907af4 HEAD@{4}: commit: a v2
312f1c9 (HEAD -> master) HEAD@{5}: commit: a v1
4eac3ad HEAD@{6}: commit: 0
239b651 HEAD@{7}: commit (initial): a.txt v1.0
git revert
如果我们修改了某些内容,已经commit到本地仓库,并且push到远程仓库了,这种情况下想把本地和 远程仓库都回退到某个版本,该怎么做呢
对于已经把代码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 <commitid> #撤销指定的版本,撤销也会作为一次提交进行保存。
reset和revert区别
git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
git reset是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容跟要
revert的内容正好相反,能够抵消要被revert的内容。
10 创建分支和合并分支
#查看分支,默认只有master分支
[root@c7-git-81 myapp]# git branch
* master
[root@c7-git-81 myapp]# echo master data v1.0 > f1.txt
[root@c7-git-81 myapp]# echo f2 > f2.txt
[root@c7-git-81 myapp]# git add .
[root@c7-git-81 myapp]# git commit -am 'add two files'
[master 2bcdb6f] add two files
1 file changed, 1 insertion(+), 1 deletion(-)
#切换分支
[root@c7-git-81 myapp]# git branch dev
[root@c7-git-81 myapp]# git branch
dev
* master
[root@c7-git-81 myapp]# git checkout dev
Switched to branch 'dev'
[root@c7-git-81 myapp]# git branch
* dev
master
#查看分支内容
[root@c7-git-81 myapp]# ls
a.txt f1.txt f2.txt
[root@c7-git-81 myapp]# cat f1.txt
master data v1.0
[root@c7-git-81 myapp]# cat f2.txt
f2
#修改分支文件内容
[root@c7-git-81 myapp]# echo dev data v1.0 > f1.txt
[root@c7-git-81 myapp]# git commit -am 'modify f1.txt'
[dev 36e1da8] modify f1.txt
1 file changed, 1 insertion(+), 1 deletion(-)
#切回原分支,修改数据
[root@c7-git-81 myapp]# git checkout master
Switched to branch 'master'
[root@c7-git-81 myapp]# echo f1.txt master data v2.0 > f1.txt
[root@c7-git-81 myapp]# git commit -am "f1.txt v2.0"
[master 10c7809] f1.txt v2.0
1 file changed, 1 insertion(+), 1 deletion(-)
[root@c7-git-81 myapp]# git log --pretty --oneline --graph --all
* 10c7809 (HEAD -> master) f1.txt v2.0
| * 36e1da8 (dev) modify f1.txt
|/
* 2bcdb6f add two files
* 312f1c9 a v1
* 4eac3ad 0
* 239b651 a.txt v1.0
#快进式合并:切换分支至dev分支,此分支为被合并的目标分支
[root@c7-git-81 myapp]# git checkout dev
Switched to branch 'dev'
#合并master分支到当前分支dev
#交互式合并
[root@c7-git-81 myapp]# git merge master
#或者非交互式
[root@c7-git-81 myapp]# git merge master -m "merge master"
#需要修改的改,需要保留的保留
[root@c7-git-81 myapp]# cat f1.txt
<<<<<<< HEAD
dev data v1.0
=======
f1.txt master data v2.0
>>>>>>> master
[root@c7-git-81 myapp]# git log --pretty --oneline --graph --all
* 1f745d4 master and dev
|\
| * c1ca014 f1.txt v2.0
* | eaa4fad modify f1.txt
|/
* c2ee8fe add two files
#三路合并:平行分支(有多次独立的提交的多个分支)中因为不同分支中同一个文件内容不同,会出现冲突,需要手动解决冲突,并重新add和commit
[root@c7-git-81 myapp]# git log --pretty --oneline --graph --all
* f24adc9 all v1.0
|\
| * 7a13504 hotfix v1.0
* | 1f745d4 master and dev
|\ \
| |/
| * c1ca014 f1.txt v2.0
* | eaa4fad modify f1.txt
|/
* c2ee8fe add two files
11 修改分支名称
[root@c7-git-81 myapp]# git branch
* dev
hotfix
master
[root@c7-git-81 myapp]# git checkout dev
Already on 'dev'
[root@c7-git-81 myapp]# git branch -M devel
[root@c7-git-81 myapp]# git branch
* devel
hotfix
master
12 当前状态打 tag 并利用 tag 回滚
[root@c7-git-81 myapp]# echo v1.0 > a.txt;git add .;git commit -m v1.0
[devel 8a971b1] v1.0
1 file changed, 1 insertion(+)
create mode 100644 a.txt
[root@c7-git-81 myapp]# git tag v1.0
[root@c7-git-81 myapp]# git tag
v1.0
[root@c7-git-81 myapp]# echo v2.0 > a.txt ;git add .;git commit -m v2.0
[devel 755e1dd] v2.0
1 file changed, 1 insertion(+), 1 deletion(-)
[root@c7-git-81 myapp]# git tag v2.0
[root@c7-git-81 myapp]# git show v1.0
commit 8a971b1225e382a512929f46b37aa8bd17c35b68
Author: jiutingqiu <jiutingqiu@163.com>
Date: Sat Feb 17 22:56:48 2024 -0800
v1.0
diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..6b3126c
--- /dev/null
+++ b/a.txt
@@ -0,0 +1 @@
+v1.0
[root@c7-git-81 myapp]# git reset --hard v1.0
HEAD is now at 8a971b1 v1.0
[root@c7-git-81 myapp]# cat a.txt
v1.0
13 本地代码提交给公用仓库码云
[root@c7-git-81 ~]# mkdir -p /data/myweb ;cd /data/myweb
[root@c7-git-81 myweb]# git init
Initialized empty Git repository in /data/myweb/.git/
[root@c7-git-81 myweb]# git config --global user.name "jiutingqiu"
[root@c7-git-81 myweb]# git config --global user.email "jiutingqiu@163.com"
[root@c7-git-81 myweb]# echo Hello World > hello.html
[root@c7-git-81 myweb]# git add .
[root@c7-git-81 myweb]# git commit -m "v1.0"
[master (root-commit) f9cf13f] v1.0
1 file changed, 1 insertion(+)
create mode 100644 hello.html
#先注册并登录码云,创建名称为myweb的未初始化的空仓库后,可以执行下面操作建立本地仓库和远程码云的联系
[root@c7-git-81 myweb]# git remote add origin https://gitee.com/jiutingqiu/myweb.git
[root@c7-git-81 myweb]# git push -u origin "master"
Username for 'https://gitee.com':xxxxx
Password for 'https://xxxxx@gitee.com':
Counting objects: 3, done.
Writing objects: 100% (3/3), 214 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/jiutingqiu/myweb.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
#再推送一下
[root@c7-git-81 myweb]# echo Hello World 2.0 >> hello.html
[root@c7-git-81 myweb]# git add .
[root@c7-git-81 myweb]# git commit -m "v2.0"
[master 27c6113] v2.0
1 file changed, 1 insertion(+)
[root@c7-git-81 myweb]# git push -u origin master
Username for 'https://gitee.com': jiutingqiu
Password for 'https://jiutingqiu@gitee.com':
Counting objects: 5, done.
Writing objects: 100% (3/3), 253 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/jiutingqiu/myweb.git
f9cf13f..27c6113 master -> master
Branch master set up to track remote branch master from origin.
#删除关联
[root@c7-git-81 myweb]# git remote remove origin
[root@c7-git-81 myweb]# git remote -v
git 合并 commit
git rebase -i HEAD~
二、私有软件仓库GitLab
1、GitLab 介绍
1.Gitlab 介绍
GitLab 是一个基于Ruby on Rails构建用于仓库管理系统的开源项目,使用Git作为代码管理工具,提供 了Web界面进行访问公开的或者私有的项目
2.GitLab 架构
Gitlab 是一个由很多应用组成复杂的系统
https://panlw.github.io/15365441001781.html
Gitlab的服务构成
Nginx:静态web服务器
GitLab shell:用于处理基于ssh会话的Git命令和修改authorized keys列表
gitlab-workhorse:轻量级的反向代理服务器,它旨在充当智能反向代理,以帮助整个 GitLab 加速
unicorn:An HTTP server for Rack applications, GitLab Rails应用是托管在这个服务器上面的
Gitaly:Git RPC service for handing all Git calls made by GitLab
Puma (GitLab Rails):处理发往Web接口和API的请求
postgresql:数据库
redis:缓存数据库
sidekiq:用于在后台执行队列任务(异步执行)
GitLab Exporter:GitLab指标暴露器
Node Exporter:节点指标暴露器
GitLab self-monitoring的多个组件:Prometheus、Alertmanager、Grafana、Sentry和Jaeger
Inbound emails(SMPT):接收用于更新issue的邮件
Outbound email (SMTP):向用户发送邮件通知
LDAP Authentication:LDAP认证集成
MinIO:对象存储服务
Registry:容器注册表,支持Image的push和pull操作
Runner:执行GitLab的CI/CD作业
Omnibus GitLab
由于Gitlab 组件众多,各个组件的分别管理配置过于复杂,所以官方提供了 Omnibus GitLab 项目实现方便 的管理
Omnibus GitLab是基于Chef的应用编排工具,它基于Chef的cookbooks和recipes等组件自动化编排 GitLab的各组件,避免了用户复杂的配置过程
3.GitLab 安装
GitLab 有两个版本:EE商业版和CE社区版,以下使用CE版
[root@c7-git-81 ~]# wget http://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-16.9.0-ce.0.el7.x86_64.rpm
[root@c7-git-81 ~]# yum -y install ./gitlab-ce-16.9.0-ce.0.el7.x86_64.rpm
4.修改 GitLab 配置
gitlab相关的目录:
/etc/gitlab #配置文件目录,重要
/var/opt/gitlab #数据目录,源代码就存放在此目录,重要
/var/log/gitlab #日志目录
/run/gitlab #运行目录,存放很多的数据库文件
/opt/gitlab #安装目录
gitlab初始化配置
[root@c7-git-81 ~]# grep "^[a-Z]" /etc/gitlab/gitlab.rb
external_url 'http://www.jiutingqiu.com'
#可选修改邮箱
# gitlab_rails['smtp_enable'] = true
# gitlab_rails['smtp_address'] = "smtp.server"
# gitlab_rails['smtp_port'] = 465
# gitlab_rails['smtp_user_name'] = "smtp user"
# gitlab_rails['smtp_password'] = "smtp password"
# gitlab_rails['smtp_domain'] = "example.com"
# gitlab_rails['smtp_authentication'] = "login"
# gitlab_rails['smtp_enable_starttls_auto'] = true
# gitlab_rails['smtp_tls'] = false
# gitlab_rails['smtp_pool'] = false
# gitlab_rails['gitlab_email_from'] = 'example@example.com'
#可选
# nginx['listen_port'] = nil #修改nginx代理监听的端口
gitlab_sshd['enable']=true #是否启用sshd服务
gitlab_sshd['listen_address']='0.0.0.0:2222' #ssh协议端口,地址ssh://git@gitlab.wang.org:2222/example/app.git
#新版中增加下面行,给root用户指定初始密码才能登录,或者设置环境变量GITLAB_ROOT_PASSWORD实现初始密码
#注意:密码至少8位并且复杂度要求才是有效密码
gitlab_rails['initial_root_password'] = "wjtq@123456"
[root@c7-git-81 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.29.7.81 www.jiutingqiu.com
2、初始化和启动服务
1.执行配置reconfigure并启动服务:
#每次修改完配置文件都需要执行此操作
[root@c7-git-81 ~]# gitlab-ctl reconfigure
2.验证 GitLab 启动完成
[root@c7-git-81 ~]# gitlab-ctl status
run: alertmanager: (pid 6797) 2447s; run: log: (pid 6605) 2491s
run: gitaly: (pid 6771) 2448s; run: log: (pid 5829) 2614s
run: gitlab-exporter: (pid 6762) 2449s; run: log: (pid 6424) 2509s
run: gitlab-kas: (pid 6078) 2604s; run: log: (pid 6096) 2601s
run: gitlab-workhorse: (pid 6732) 2451s; run: log: (pid 6293) 2528s
run: logrotate: (pid 5708) 2629s; run: log: (pid 5747) 2626s
run: nginx: (pid 6746) 2449s; run: log: (pid 6317) 2523s
run: node-exporter: (pid 6750) 2449s; run: log: (pid 6374) 2517s
run: postgres-exporter: (pid 6807) 2446s; run: log: (pid 6639) 2487s
run: postgresql: (pid 5885) 2610s; run: log: (pid 5964) 2607s
run: prometheus: (pid 6782) 2448s; run: log: (pid 6545) 2499s
run: puma: (pid 6164) 2542s; run: log: (pid 6171) 2541s
run: redis: (pid 5758) 2623s; run: log: (pid 5767) 2622s
run: redis-exporter: (pid 6764) 2448s; run: log: (pid 6447) 2505s
run: sidekiq: (pid 6194) 2536s; run: log: (pid 6210) 2535s
3.验证端及状态
80端口是在初始化gitlib的时候启动的,因此如果之前有程序占用了相关端口,就会导致初始化失败或无法访问
[root@c7-git-81 ~]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 6746 root 7u IPv4 72070 0t0 TCP *:http (LISTEN)
nginx 6752 gitlab-www 7u IPv4 72070 0t0 TCP *:http (LISTEN)
nginx 6753 gitlab-www 7u IPv4 72070 0t0 TCP *:http (LISTEN)
nginx 6754 gitlab-www 7u IPv4 72070 0t0 TCP *:http (LISTEN)
nginx 6755 gitlab-www 7u IPv4 72070 0t0 TCP *:http (LISTEN)
4.Gitlab的常用命令
GitLab除了使用Web界面进行管理,还提供了各组件的统一命令为gitlab-ctl,此外还有一些各组件专用 的命令,如gitlab-pgsql、 gitlab-rails和gitlab-rake等
#客户端命令行操作行
gitlab-ctl
gitlab-ctl check-config #检查配置
gitlab-ctl show-config #查看配置
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 #列出服务
#其它命令
gitlab-rails #用于启动控制台进行特殊操作,如修改管理员密码、打开数据库控制台( gitlab-rails dbconsole)等
gitlab-psql #数据库命令行
gitlab-rake #数据备份恢复等数据操作
3、GitLab 基本配置
1.GitLab登陆
2.修改中文
3.关闭账号注册功能