代码版本控制系统

1.学习背景

当公司的服务器架构越来越复杂,需要频繁的发布新配置文件,以及新代码;
但是如果机器部署数量较多,发布的效率必然很低;
并且如果代码没有经过测试环境,预生产环境层层测试,最终才到生产环境,不经过测试的部署,会导致很严重的bug,因此必须要进行一定的代码测试。

因此从devops部署理念来看,任何一家单位都必须实现CICD(持续集成、持续交付)的理念,实现自动化代码集成、自动化代码部署。

目前主流的解决方案,学习的技术就是

  • git
  • jenkins
  • gitlab

2.什么是devops开发流程

DevOps是一种实现Dev(开发)与Ops(运维)工作流有效联合的运维文化理念。

为什么要理解devops?

image-20220706153353986

越是高级的运维,越是要了解开发与运维的有效结合工作,推进运维自动化工作,提升运维效率。

一个软件开发团队,会包括

项目经理,系统架构师、前端开发者,后端开发者,测试工程师,网络工程师,运维工程师等
如何让软件在开发、测试、运维及最终发布之间进行有效的流动,这就是DevOps所要关注的重点。

DevOps是一种文化,一种理念,是一种把开发(Dev)、测试(Test)、运维(Ops)及最终发布(CR)工作流进行联合的思想。

2.1 devops如何实践

- 所有环境和代码使用同一个仓库,将软件包纳入版本管理
- 团队共同决定发布流程
- 保持 DEV、TEST、PRODUCTION 环境的一致性
- 自动化回归测试,回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。
- 小步提交,每日部署;而不是一次部署大量变更 
- 更快、更频繁发布

3.版本控制系统

什么是“版本控制”?我为什么要关心它呢? 

版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。

3.1 你自己本地怎么管理文件?

许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。

这么做唯一的好处就是简单,但是特别容易犯错。

有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件。

如果你在学校写过毕业论文,那你一定遇见过这样的问题

image-20200706140045980

一个论文翻来覆去的改,写一点觉得有问题,写一点还觉得有问题,还不容易写好了,导师还挑刺,说这改的还不如上回,给改回去、、、

  • 看着这一堆乱七八糟的文件,你自己也不记得,每一个文件到底写了什么内容,还得一个个看,想删又不敢删。。。
  • 当你写完了毕业论文,你还得用U盘拷给导师,或者发个邮件给他,但是你回家可能还得改论文,那你发给导师的论文和你本地最新的论文又不一致了。。

于是这么多令人fuck指的操作,你就希望有没有一个软件

帮你记录文件变动的操作,并且同事还能一起操作,不需要自己传输文件,想知道变动了什么,只需要去软件里看看,这是不是很nb?

3.1.1 例如nginx配置文件的多人修改

如图,会发生什么结果?

image-20220706154608012

3.2 这个软件雏形?

对于文件使用版本号,日期的管理,这种方式比起没有版本管理好得多,但是也很臃肿,且他人不容易看得懂

版本 文件名 用户 说明 日期
1 美国皇家大学毕业论文v1.doc yuchao 论文初稿 7/12 10:38
2 美国皇家大学毕业论文v2.doc yuchao 论文修改版 7/12 18:09
3 美国皇家大学毕业论文v3.doc Onlyu 小于帮我修改论文 7/13 9:51
4 美国皇家大学毕业论文v4.doc Wupeiqi 武沛奇帮我修改论文 7/14 15:17

3.3 新式版本控制

现在的版本控制系统又是如何管理的,且还能实现快速回退功能。

image-20200706141239759


image-20220706154806436

4.什么是集成(CI)

CI/CD是现代软件开发中的重要方法,能大幅提升开发效率和软件质量。下面为你详细介绍CI/CD和CI的概念、主要区别以及关键工具。

CI(持续集成)

概念
CI指的是开发人员将代码频繁地集成到共享仓库的流程。每次集成都通过自动化构建(包括编译、测试、代码分析等)来验证,尽早发现集成错误。

核心特点

  • 频繁提交:开发人员每天多次将代码提交到主干分支。
  • 自动化构建与测试:提交后自动触发构建和测试流程,确保新代码与现有代码兼容。
  • 快速反馈:若构建或测试失败,立即通知开发团队修复。

关键工具

  • 版本控制:Git、SVN
  • 自动化构建:Jenkins、GitLab CI、CircleCI
  • 测试框架:JUnit(Java)、Pytest(Python)、Jest(JavaScript)

示例流程

  1. 开发人员提交代码到Git仓库。
  2. CI工具(如Jenkins)检测到提交,触发自动化构建。
  3. 执行编译、单元测试、代码质量检查。
  4. 若所有步骤通过,代码被认为“可集成”;否则返回错误报告。

CD(持续交付/部署)

概念
CD有两种常见解释:

  1. 持续交付(Continuous Delivery)
    确保代码通过自动化测试后,可以随时部署到生产环境,但部署需人工触发。
  2. 持续部署(Continuous Deployment)
    代码通过自动化测试后自动部署到生产环境,无需人工干预。

核心特点

  • 自动化部署流水线:从测试到预生产环境再到生产环境的全流程自动化。
  • 环境一致性:开发、测试、生产环境配置相同,减少“环境差异导致的问题”。
  • 快速迭代:支持快速发布新功能或修复bug。

关键工具

  • 容器化:Docker、Kubernetes
  • 部署工具:Ansible、Terraform、AWS CodeDeploy
  • 监控工具:Prometheus、Grafana、Sentry

示例流程(以持续部署为例):

  1. 代码通过CI阶段的所有测试。
  2. 自动打包为Docker镜像并推送到容器 registry。
  3. Kubernetes自动部署新版本到生产环境。
  4. 监控系统验证部署成功并持续监控应用状态。

CI/CD的优势

  • 快速反馈:尽早发现并修复问题,降低返工成本。
  • 减少手动错误:自动化流程减少人为失误。
  • 提高协作效率:团队成员共享统一的代码基线。
  • 支持快速迭代:加速新功能上线速度,提升用户体验。

总结

CI是CD的基础,强调代码的频繁集成和自动化验证;CD则进一步扩展到自动化部署,实现从代码提交到生产环境的无缝衔接。两者共同构成了现代DevOps实践的核心。

4.1 什么是持续集成(CI)

持续集成(Continuous integration ,CI)

持续集成就是在于”持续“两字,频繁的(一天多次)的将代码集成到主干(master),重复如上的工作。

image-20200706111723922

说白了就是你公司要部署一套系统,能支持,让所有的开发人员,都可以快速、集中式的提交代码,整合到一个主干线。

程序员本地写代码,通过git管理

↓推代码

git仓库,gitlab,github

↓仓库通知CI服务器,jenkins

jenkins执行脚本,如对代码编译,测试,运行

↓通知集成结果

这里属于第一道流水线的测试完毕。

4.2 使用持续集成好处

持续集成(CI)是现代软件开发中的关键实践,通过自动化构建、测试和反馈机制,显著提升开发效率和软件质量。以下是使用CI的主要好处:

1. 快速发现并修复错误

  • 早发现问题:每次代码提交后自动触发构建和测试,及时发现集成错误(如依赖冲突、语法错误)。
  • 降低修复成本:在开发早期修复问题的成本远低于后期(如测试阶段或生产环境)。
  • 示例:单元测试失败时立即通知开发者,避免错误累积。

2. 提高代码质量

  • 强制代码规范:通过自动化代码检查(如静态分析工具)确保代码符合最佳实践。
  • 减少技术债务:持续验证代码质量,避免不良模式或冗余代码积累。
  • 工具支持:ESLint(JavaScript)、Pylint(Python)、Checkstyle(Java)等。

3. 增强团队协作效率

  • 频繁集成:鼓励开发者每天多次提交代码,减少分支冲突。
  • 共享代码基线:所有团队成员在统一的代码版本上工作,降低“版本不一致”问题。
  • 透明化流程:构建和测试结果对整个团队可见,促进沟通和责任共担。

4. 缩短反馈周期

  • 即时反馈:自动化流程在几分钟内返回结果,开发者无需等待长时间的手动测试。
  • 快速迭代:快速验证新功能或修复,加速开发节奏。
  • 数据驱动决策:通过测试覆盖率、构建成功率等指标优化开发流程。

5. 支持自动化部署(CD)

  • CI是CD的基础:稳定的持续集成是实现持续交付/部署的前提。
  • 无缝衔接后续流程:通过CI验证的代码可直接进入自动化部署流水线。

6. 降低风险

  • 渐进式变更:小步提交代码,而非大规模合并,降低引入重大缺陷的风险。
  • 回滚机制:若发现问题,可快速回滚到上一个稳定版本。

7. 节省时间和资源

  • 减少手动工作:自动化构建、测试和部署取代重复性劳动。
  • 优化资源利用:并行执行测试用例,充分利用计算资源。

8. 提升用户体验

  • 更快交付价值:通过快速迭代及时响应用户需求。
  • 更高可靠性:减少生产环境故障,提升系统稳定性。

实践案例

  • GitHub:每次PR触发自动化测试,确保合并前代码质量。
  • Netflix:每天通过CI/CD部署数千次,依赖强大的自动化测试体系。
  • Google:通过Bazel等工具实现大规模代码库的高效构建和测试。

总结

持续集成通过自动化和频繁反馈,将传统软件开发中的“集成地狱”转化为高效、可预测的流程。它不仅提升了代码质量和团队协作,还为持续交付/部署奠定了基础,是现代DevOps实践中不可或缺的一环。

4.3 不做CI行不行

行,如果你的规模太小,也就没必要部署这套系统了,写点部署脚本就完事了。

但是如果项目较大,且较复杂,需要不断的加新功能,或者升级产品,因此必须引入CI系统。

5.什么是持部署(CD)

持续部署(Continuous Deployment)是软件开发中的一种自动化实践,属于CI/CD流程的终极阶段。它通过自动化流水线,将通过测试的代码直接部署到生产环境,无需人工干预。以下是其核心概念、特点及价值:

1. 核心概念

  • 自动化到底:代码提交后,经过构建、测试、部署的全流程自动化,最终自动上线到生产环境。
  • 无需人工审批:一旦测试通过,系统自动完成部署,无需等待人为确认(不同于持续交付需人工触发部署)。
  • 高频发布:支持一天内多次向用户交付新功能或修复。

2. 关键特点

(1)全自动化流水线

  • 从代码提交到生产环境的所有环节(构建、测试、部署、监控)均由自动化工具完成。
  • 工具链示例
    graph TD
      A[代码提交] --> B{CI服务器}
      B --> C[自动化测试]
      C --> D[构建镜像]
      D --> E[部署到预生产环境]
      E --> F[自动化冒烟测试]
      F --> G[部署到生产环境]
    

(2)严格的质量门禁

  • 依赖强大的自动化测试(单元测试、集成测试、端到端测试)确保代码质量。
  • 任何测试失败都会阻止部署流程,避免问题代码上线。

(3)快速回滚机制

  • 若部署后监控发现异常(如性能下降、错误率飙升),自动回滚到上一版本。
  • 示例工具:Kubernetes的滚动更新、AWS CodeDeploy的自动回滚策略。

(4)环境一致性

  • 开发、测试、生产环境的配置完全一致(如使用Docker容器、基础设施即代码),避免“在测试环境正常,生产环境报错”的问题。

3. 与持续交付的区别

特性 持续交付(Continuous Delivery) 持续部署(Continuous Deployment)
人工干预 需要人工触发部署到生产环境 自动部署到生产环境,无需人工干预
上线频率 通常较低(如每周/月) 可高达每天数十次
风险控制 人工决策降低风险 依赖自动化测试和监控降低风险
适用场景 对变更敏感的行业(金融、医疗) 互联网产品、快速迭代的应用

4. 持续部署的价值

(1)加速价值交付

  • 更快响应用户需求:新功能或修复可在几分钟内到达用户手中。
  • 数据驱动优化:通过A/B测试快速验证功能效果,迭代优化。

(2)减少人为错误

  • 消除手动部署中的配置错误、版本不一致等问题。
  • 部署过程标准化,结果可预测。

(3)提升团队效率

  • 开发人员无需等待部署流程,专注于编写代码。
  • 运维团队从重复性工作中解放,转向更有价值的架构优化。

(4)增强系统稳定性

  • 小步快跑式的变更降低单次部署风险。
  • 自动化监控及时发现并处理问题。

5. 实施挑战与前提条件

挑战

  • 测试覆盖率要求极高:需确保自动化测试覆盖各种场景(如边界条件、异常处理)。
  • 文化转变:团队需接受“快速失败、快速修复”的理念,而非追求“零缺陷”。
  • 监控系统压力:需实时监控生产环境,快速响应问题。

前提条件

  • 成熟的CI基础:持续集成流程稳定运行,测试通过率高。
  • 基础设施自动化:使用Docker、Kubernetes等工具实现环境一致性。
  • 完善的监控体系:实时收集性能、错误、用户行为数据。

6. 典型工具链

  • 版本控制:Git、GitLab
  • CI/CD平台:Jenkins、GitLab CI、CircleCI、GitHub Actions
  • 容器化:Docker、Kubernetes
  • 部署工具:Ansible、Terraform、AWS CodeDeploy
  • 监控工具:Prometheus、Grafana、Sentry、ELK Stack

7. 实践案例

  • Netflix:每天通过CD部署数千次,依赖混沌工程(Chaos Engineering)确保系统韧性。
  • Amazon:部分服务实现11秒完成从代码提交到生产部署的全流程。
  • Spotify:通过“部落(Tribe)-小队(Squad)”组织架构支持独立团队的快速部署。

总结

持续部署是DevOps的终极目标,通过极致自动化实现软件交付的“光速”迭代。虽然实施难度较高,但对追求快速创新、用户体验至上的企业而言,它是提升竞争力的关键手段。

当你部署了一套基于 git + gitlab + jenkins + shell  的持续集成、持续部署系统之后

就可以实现快速的代码快速更新,快速发布,且因为经过了测试,保证了代码质量。
因为如果开发李四,写的新功能代码有bug,当你基于jenkins对代码测试之后,定位bug、通知程序修复bug,最终再整合最新的代码到master主线上。

这个自动化流程能极大提高生产级别的开发、测试、运维效率了。

image-20200706133434092

1. 程序员张三开发代码,git push 推送到 代码仓库
2. 开发老大,合并张三写的代码到master主线
3. 测试人员介入,进行代码的功能测试、白盒测试等
4. 代码测试验收完毕,运维基于jenkins实现代码部署到生产环境。

5.1 如何实现CD

当有人提交了代码,就自动的通知jenkins对代码进行构建 > 测试 > 确认代码可运行  > 构建到生产服务器 

整个过程全自动化,但是有可能出现难以预料的问题

最好的是半自动化,使用持续交付(人工介入+jenkins发布),也不能过于自动化,容易翻车。

6.版本控制系统介绍

6.1 SVN

SVN(Subversion)是一种集中式版本控制系统(CVCS),诞生于2000年,旨在替代当时广泛使用的CVS。它通过中央服务器管理代码库,让团队成员能够协同开发并追踪代码变更。以下是SVN的核心概念、特点及与Git的对比:

1. 核心概念

(1)集中式架构

  • 中央仓库:所有代码和历史记录存储在单一服务器上。
  • 客户端-服务器模式:开发者需从中央仓库获取(checkout)最新代码,修改后提交(commit)回服务器。

(2)版本控制单位

  • 文件与目录:SVN直接管理文件和目录的变更,每次提交记录路径变化。

(3)原子提交

  • 提交操作是原子性的,要么全部成功,要么全部失败,确保仓库状态一致性。

(4)全局版本号

  • 每次提交生成唯一的全局版本号(如r1234),标识整个仓库的状态。

2. 基本操作

仓库操作

  • svnadmin create <仓库路径>:创建新仓库
  • svn checkout <仓库URL>:从服务器获取代码到本地

日常开发

  • svn update:拉取服务器最新变更
  • svn add <文件>:添加新文件到版本控制
  • svn delete <文件>:删除文件
  • svn commit -m "说明":提交变更到服务器
  • svn status:查看文件状态

历史与差异

  • svn log:查看提交历史
  • svn diff:查看文件差异

3. 分支与合并

分支机制

  • 通过复制目录实现分支(如branches/feature-x),本质是文件系统操作。
  • 创建分支成本较高(需复制整个目录树)。

合并策略

  • 支持基于修订号或时间点的合并,但合并逻辑相对复杂,需手动处理较多冲突。

4. 权限管理

  • 通过配置文件(如authz)控制用户对目录的读写权限。
  • 支持基于路径的访问控制(如/trunk仅限管理员修改)。

5. 与Git的对比

特性 SVN(集中式) Git(分布式)
架构 中央服务器存储所有历史 每个客户端完整复制仓库
离线工作 依赖网络连接 完全离线工作,本地提交
分支成本 高(复制整个目录) 极低(创建指针)
版本号 全局递增(如r1234) 基于内容的哈希值(如abc123
提交范围 仅提交到中央仓库 先提交到本地,再推送到远程
冲突处理 合并时可能产生较多冲突 更智能地处理合并冲突
适合场景 小型团队、文件导向的项目 大型团队、复杂分支管理的项目

6. SVN的优缺点

优点

  • 简单易用:概念直观,学习曲线平缓。
  • 权限精细:支持基于路径的严格权限控制。
  • 适合文件管理:对二进制文件(如图像、文档)的版本控制友好。

缺点

  • 单点故障:中央服务器故障时无法工作。
  • 分支效率低:创建和切换分支耗时较长。
  • 扩展性有限:处理超大规模代码库时性能下降。

7. 典型工具与应用场景

工具

  • 命令行客户端:随SVN服务器安装,提供基础功能。
  • TortoiseSVN:Windows下的图形化客户端,集成到资源管理器。
  • Cornerstone:Mac下的图形化客户端。

适用场景

  • 小型团队协作(如3-10人)。
  • 对文件权限管理要求严格的项目(如企业文档管理)。
  • 无需频繁分支的稳定项目(如嵌入式开发)。

8. SVN vs Git:如何选择?

  • 选SVN:若团队规模小、需严格权限控制、较少使用分支,或项目依赖SVN特有功能(如基于路径的权限)。
  • 选Git:若团队规模大、需频繁分支合并(如敏捷开发),或需离线工作、强大的分布式协作能力。

总结

SVN作为集中式版本控制的代表,以其简单性和严格的权限管理在特定场景中仍有价值。但随着分布式版本控制系统(如Git)的普及,SVN在大规模协作和复杂开发流程中的局限性逐渐显现。对于现代软件开发,Git已成为主流选择,而SVN更适合对稳定性和权限管理要求较高的传统项目。

集中式版本控制系统,很老旧的技术公司会用。

Linus一直痛恨的CVS及SVN都是集中式的版本控制系统,而Git是分布式版本控制系统,集中式和分布式版本控制系统有什么区别呢?

先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。

中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。

SubVersioN(SVN)

工作模式就是

1. 每一个人复制一份源码到本机修改
2. 各自修改完毕后,再一一合并为统一的源码

复制 > 修改 > 合并

image-20220706162324859

集中式版本控制,典型代表SVN

集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊。

而且如果SVN集中式仓库服务器挂了,所有人都再无法使用、提交、下载数据。

6.2 GIT 分布式版本控制系统

Git是一款开源的分布式版本控制系统(DVCS),广泛应用于软件开发中,用于高效管理代码变更、支持团队协作和版本追溯。以下是Git的核心概念、工作模式及优势:

1. 核心概念

(1)分布式架构

  • 去中心化:每个开发者的本地仓库都是完整的代码库,包含全部历史记录和分支信息。
  • 离线工作:无需联网即可提交、查看历史、创建分支,联网后再同步到远程仓库。

(2)提交对象(Commit)

  • 不可变快照:每次提交保存文件的完整状态,而非差异。
  • 哈希标识:每个提交通过SHA-1哈希值唯一标识(如c3a023e...)。
  • 父子关系:提交形成链式结构,支持回溯历史。

(3)分支(Branch)

  • 轻量级指针:分支是指向提交的可变指针,创建和切换成本极低。
  • 并行开发:支持同时在多个分支上独立开发(如mainfeature-x)。

(4)暂存区(Staging Area)

  • 选择性提交:通过git add将文件放入暂存区,精细控制提交内容。

2. 基本操作流程

仓库初始化与克隆

git init        # 初始化本地仓库
git clone <URL> # 克隆远程仓库到本地

日常开发循环

git status      # 查看文件状态
git add <文件>  # 添加修改到暂存区
git commit -m "说明" # 提交到本地仓库
git push        # 推送到远程仓库
git pull        # 拉取并合并远程更新

分支管理

git branch      # 列出分支
git branch <名称> # 创建分支
git checkout <分支> # 切换分支
git merge <分支>  # 合并分支
git branch -d <分支> # 删除分支

3. 工作区、暂存区与本地仓库

Git的三层结构:

  1. 工作区(Working Directory):实际编辑文件的地方。
  2. 暂存区(Staging Area/Index):准备提交的文件快照。
  3. 本地仓库(Local Repository):已提交的历史记录。
graph LR
    A[工作区] -->|git add| B(暂存区)
    B -->|git commit| C{本地仓库}
    C -->|git push| D[远程仓库]
    D -->|git pull| C

4. 远程协作模式

集中式工作流

  • 单一远程仓库(如GitHub),团队成员直接推送/拉取。
  • 适合小型团队和简单项目。

Fork工作流

  • 每个开发者拥有自己的远程仓库(fork),通过PR(Pull Request)贡献代码。
  • 适合开源项目(如Linux内核),无需直接访问主仓库。

Git Flow

  • 严格的分支模型(maindevelopfeaturereleasehotfix)。
  • 适合需要严格发布流程的项目。

5. 与SVN的关键区别

特性 Git(分布式) SVN(集中式)
架构 去中心化,本地完整仓库 中心化,依赖中央服务器
分支成本 极轻量(毫秒级) 重量级(需复制文件)
离线工作 完全支持 依赖网络连接
提交范围 本地提交,后同步到远程 直接提交到中央服务器
版本号 基于内容的哈希值(如c3a023e 递增的全局编号(如r1234
冲突处理 更智能,支持多种合并策略 手动处理为主

6. Git的优势

  • 速度与性能:本地操作无需网络,分支切换毫秒级响应。
  • 强大的分支与合并:支持复杂的并行开发场景。
  • 数据完整性:通过哈希校验确保代码不被篡改。
  • 丰富的工具链:GitHub、GitLab、Bitbucket等平台提供集成协作功能。
  • 社区支持:几乎所有开源项目都使用Git,学习资源丰富。

7. 常见工具与扩展

  • 命令行工具:Git基础命令。
  • 图形界面:GitKraken、SourceTree、GitHub Desktop。
  • 集成开发环境:VS Code、IntelliJ IDEA内置Git支持。
  • 持续集成:Jenkins、GitLab CI/CD与Git无缝集成。

总结

Git凭借其分布式架构、高效的分支模型和强大的协作能力,已成为现代软件开发的标配。无论是个人项目还是大型团队协作,Git都能提供可靠的版本控制解决方案,帮助开发者更好地管理代码变更和历史。

image-20220706163354181

6.3 git特点

1. git是分布式的,特点是保存本地文件的元数据(meta data,文件属性等),将本地文件所有的的元信息,记录在git repo里的.git隐藏文件夹中。

2. git的使用可以不用网络,因为本地版本控制仓库就在你自己机器上,每一个人就是一个完成的版本库。
只不过是最终将你的本地仓库,作为一个分支,推送、合并到一个统一的线上代码仓库主干线即可,实现代码集成。

7.git软件安装

Git有多种方式使用

  • 原生命令行,才能使用git所有命令,会git命令再去用gui图形工具,完全无压力
  • GUI图形软件,只是实现了git的部分功能,以减免操作难度,难以记住git原生命令
  • 不同的人会有不同的GUI图形工具,但是所有人用的git原生命令都一样,推荐学习命令

7.1 windows装git

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

image-20220706164522354

7.2 linux\macos

https://git-scm.com/download/
也是一样,下载安装即可

[root@cicd-99 ~]#yum install git -y


# 查看版本
root@cicd-99 ~]#git --version
git version 1.8.3.1

8.git身份设置

ubuntu

在使用Git进行开发前,配置个人身份信息是必不可少的一步,因为每次提交都会包含这些信息,用于标识开发者。以下是Git身份设置的详细步骤和注意事项:

1. 配置用户名和邮箱

Git使用user.nameuser.email两个核心配置项记录身份信息。这两个值会被写入每个提交对象中,永久保存在项目历史里

全局配置(推荐)

对所有Git仓库生效:

git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

项目级配置

仅对当前仓库生效(会覆盖全局配置):

cd /path/to/your/project
git config user.name "Your Name"
git config user.email "your.email@example.com"

2. 验证配置

查看已设置的配置:

git config --list
# 输出示例:
# user.name=Your Name
# user.email=your.email@example.com

查看单个配置项:

git config user.name  # 输出:Your Name
git config user.email # 输出:your.email@example.com

3. 配置文件位置

  • 全局配置:存储在用户主目录下的.gitconfig文件(Linux/macOS)或C:\Users\YourName\.gitconfig(Windows)。
    [user]
        name = Your Name
        email = your.email@example.com
    
  • 项目配置:存储在项目根目录的.git/config文件中。

4. 最佳实践

(1)使用真实信息

  • 提交记录会公开显示在GitHub等平台上,建议使用真实姓名和常用邮箱。
  • 示例:
    git config --global user.name "张三"
    git config --global user.email "zhangsan@company.com"
    

(2)区分工作与个人项目

  • 若需要在不同项目使用不同身份,可通过项目级配置覆盖全局设置:

    # 进入工作项目目录,设置公司邮箱
    cd ~/work-project
    git config user.email "zhangsan@company.com"
    
    # 进入个人项目目录,设置个人邮箱
    cd ~/personal-project
    git config user.email "zhangsan@personal.com"
    

(3)与GitHub/GitLab邮箱保持一致

  • 提交邮箱需与代码托管平台(如GitHub)的注册邮箱一致,才能正确关联贡献记录。

5. 高级配置:条件式包含

Git 2.13+ 支持根据路径自动切换身份:

# 编辑全局配置文件
vim ~/.gitconfig

添加条件式配置:

[user]
    name = 通用用户名
    email = generic@example.com

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work

[includeIf "gitdir:~/personal/"]
    path = ~/.gitconfig-personal

创建工作和个人配置文件:

# ~/.gitconfig-work
[user]
    name = 工作姓名
    email = work@company.com

# ~/.gitconfig-personal
[user]
    name = 个人姓名
    email = personal@example.com

6. 修改历史提交的身份信息

若之前的提交使用了错误的邮箱,可通过以下脚本批量修改(谨慎操作,会重写历史):

git filter-branch --env-filter '
OLD_EMAIL="wrong@example.com"
CORRECT_NAME="Your Name"
CORRECT_EMAIL="correct@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

7. 其他有用配置

(1)设置编辑器

git config --global core.editor "vim"  # 设置Vim为默认编辑器

(2)启用颜色输出

git config --global color.ui auto

(3)设置行结束符(Windows用户注意)

# Windows: 提交时转换为LF,检出时转换为CRLF
git config --global core.autocrlf true

# Linux/macOS: 提交和检出均保持LF
git config --global core.autocrlf input

总结

正确配置Git身份是协作开发的基础,建议:

  1. 使用git config --global设置全局身份。
  2. 确保邮箱与代码托管平台一致。
  3. 对特殊项目使用项目级配置或条件式包含。
  4. 避免在提交历史中使用敏感信息。

centos

既然已经在系统上安装了 Git,你会想要做几件事来定制你的 Git 环境。 每台计算机上只需要配置一次,程序升级时会保留配置信息。 你可以在任何时候再次通过运行命令来修改它们。

回顾linux用户的概念

linux多用户,多任务

一台机器可以有多个用户登录,同时操作

因此就存在了不同的环境变量,用来区分,每个登录linux机器的用户

比如root用户的信息,在ls -a /root/

普通yuchao用户的信息,在 ls -a /home/yuchao

不同的用户登录后,linux加载不同的环境变量参数,对系统控制

Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置:

这个用户指的是linux用户

三种环境参数

  • --system
  • --global
  • --local
  • /etc/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system 选项的 git config 时,它会从此文件读写配置变量。(针对任意登录该linux的用户都生效)
  • ~/.gitconfig~/.config/git/config 文件:只针对当前用户。 可以传递 --global 选项让 Git 读写此文件。(只针对当前登录系统的用户生效)
  • 当前使用仓库的 Git 目录中的 config 文件(就是 .git/config):针对该仓库。 --local 当前仓库配置。(只针对某一个文件夹生效,例如/learn/linux/.git/config)

# 因为git是分布式版本控制系统,因为要区分出,到底是谁进行了版本管理,也就是提交的版本记录,都是有名字,有时间的

# 因此用git之前要先设置git的身份设置

git config --global user.name "pyyu"
git config --global user.email "yc_uuu@163.com"
git config --global color.ui true

列出git设置

[root@cicd-99 ~]#git config --list
user.name=pyyu
user.email=yc_uuu@163.com
color.ui=true






我们这里配置的是--global参数,因此是在用户家目录下,可以查看
[root@chaogelinux ~]# cat .gitconfig
[user]
    name = pyyu
    email = yc_uuu@163.com
[color]
    ui = true

8.1 git身份设置命令集合

yum install git -y  安装git

git --version  查看git版本

git config --system --list 查看系统所有linux用户的通用配置,此命令检查/etc/gitconfig

git config --global --list 查看当前linux用户的配置,检查~/.gitconfig文件

git config --local --list 查看git目录中的仓库配置文件,.git/config文件

git config --global user.name "pyyu"  配置当前linux用户全局用户名,这台机器所有git仓库都会用这个配置

git config --global user.email "yc_uuu@163.com"  配置当前linux用户全局邮箱

git config --global color.ui true 配置git语法高亮显示

git config --list 列出git能找到的所有配置,从不同的文件中读取所有结果

git config user.name  列出git某一项配置

git help 获取git帮助

man git man手册

git help config 获取config命令的手册

ubuntu-git命令大全

本地Git代码管理是开发流程的基础,通过合理使用分支、提交和暂存等功能,可以高效地组织和追踪代码变更。以下是本地Git代码管理的核心技巧和最佳实践:

1. 基本工作流程

(1)克隆远程仓库

git clone <远程仓库URL>
cd <项目目录>

(2)创建开发分支

git checkout -b feature/new-feature  # 创建并切换到新分支
# 等价于:
# git branch feature/new-feature
# git checkout feature/new-feature

(3)提交变更

git status                 # 查看文件状态
git add <文件>             # 添加到暂存区
git commit -m "提交说明"   # 提交到本地仓库

(4)同步远程分支

git pull origin main       # 拉取远程主分支更新
git push origin feature/new-feature  # 推送本地分支到远程

2. 分支管理策略

(1)分支类型

  • 主分支(main/master):永远保持可部署状态,仅接受测试通过的代码。
  • 开发分支(develop):集成所有功能分支的代码,用于测试。
  • 功能分支(feature/*):开发新功能,从develop分支创建,完成后合并回develop。
  • 修复分支(hotfix/*):紧急修复生产问题,直接从main分支创建,完成后合并回main和develop。

(2)创建与切换分支

git checkout -b feature/login  # 创建并切换到登录功能分支
git checkout main              # 切换回主分支

(3)合并分支

# 在develop分支上合并feature分支
git checkout develop
git merge feature/login        # 快进合并(Fast-forward)

(4)删除分支

git branch -d feature/login    # 删除已合并的分支
git branch -D feature/broken   # 强制删除未合并的分支

3. 提交技巧

(1)原子提交

  • 每个提交只包含一个逻辑变更,例如:

    # 好的提交:单一功能
    git commit -m "添加登录表单验证"
    
    # 坏的提交:多个不相关修改
    git commit -m "更新登录页,修改API地址,调整样式"
    

(2)拆分提交

  • 使用git add -p交互式选择部分修改添加到暂存区:
    git add -p  # 逐块选择要提交的修改
    

(3)修改最近提交

git commit --amend -m "修正提交说明"  # 修改提交信息
git commit --amend                  # 追加未提交的修改到上一个提交

4. 暂存与恢复

(1)临时保存未完成的修改

git stash                  # 保存当前工作区修改
git stash list             # 查看暂存列表
git stash apply            # 恢复最近一次暂存
git stash drop             # 删除最近一次暂存
git stash pop              # 恢复并删除最近一次暂存

(2)恢复文件

git checkout -- <文件>      # 丢弃工作区修改
git restore <文件>         # 同上(Git 2.23+)

(3)撤销暂存

git reset HEAD <文件>      # 取消暂存
git restore --staged <文件>  # 同上(Git 2.23+)

5. 查看历史与差异

(1)查看提交历史

git log                    # 查看提交历史
git log --oneline          # 简洁模式
git log --graph --all      # 可视化分支历史

(2)查看文件差异

git diff                   # 查看工作区与暂存区的差异
git diff --staged          # 查看暂存区与最新提交的差异
git diff HEAD~1            # 查看当前与上一个提交的差异

6. 高级操作

(1)变基(Rebase)

将多个提交整理成线性历史:

git checkout feature/new-feature
git rebase main            # 将当前分支变基到main分支

(2)交互式变基

合并、拆分或修改历史提交:

git rebase -i HEAD~3       # 编辑最近3个提交

(3) cherry-pick

将特定提交应用到当前分支:

git cherry-pick <commit-hash>  # 应用指定提交

7. 最佳实践

(1)保持分支简洁

  • 功能完成后及时删除分支,避免分支冗余。

(2)定期同步主分支

# 在功能分支上定期拉取主分支更新
git checkout feature/new-feature
git rebase main

(3)使用描述性提交信息

  • 遵循Conventional Commits规范:
    # 格式:<类型>(<范围>): <描述>
    feat(login): 添加验证码功能
    fix(api): 修复用户信息获取错误
    docs: 更新README.md
    

(4)避免提交敏感信息

  • 使用.gitignore排除敏感文件(如配置文件、密钥):
    # .gitignore示例
    *.log
    config/*.json
    node_modules/
    

8. 常见问题处理

(1)合并冲突

git merge feature/branch   # 发生冲突
git status                 # 查看冲突文件
# 手动解决冲突后
git add <冲突文件>
git commit                 # 完成合并

(2)重置错误提交

git reset --hard HEAD~1    # 回退到上一个提交,丢弃本地修改
git reset --soft HEAD~1    # 回退到上一个提交,保留本地修改

总结

本地Git代码管理的核心是:

  1. 使用分支隔离不同功能开发
  2. 通过原子提交保持历史清晰
  3. 利用暂存和恢复应对中断
  4. 定期同步远程分支
  5. 掌握变基、cherry-pick等高级操作

合理运用这些技巧,可以大幅提升开发效率,减少协作中的问题。

9.git实践原理

git本地仓库,也就是一个文件夹,这个目录下的所有内容都被git工具管理,记录了所有文件的元数据。

你在这个本地仓库中所有对文件的修改,删除,都会被git记录下状态,便于历史记录跟踪,以及还原文件状态。

9.1 三个git使用的场景

你使用git会遇见这三个场景

9.2 本地已经写好了代码,需要用git去管理

cd /home/yuchao/my_shell/

git init   # 初始化一个普通的目录为 git local repo



git init命令会创建一个.git隐藏子目录,这个目录包含初始化git仓库所有的核心文件。

此步仅仅是初始化,此时项目里的代码还没有被git跟踪,因此还需要git add对项目文件跟踪,然后git commit提交到local repo。

如果想知道git详细原理,请看
https://git-scm.com/book/zh/v2/ch00/ch10-git-internals

9.3 从零新建git本地仓库,编写代码

mkdir /home/yuchao/

[root@cicd-99 ~]#git init  /home/yuchao/happy_linux
Initialized empty Git repository in /home/yuchao/happy_linux/.git/


此步会在当前路径创建happy_linux文件夹,happy_linux文件夹中包含了.git的初始化文件夹,所有配置

9.4 克隆远程仓库中的代码

国内的码云 gitee
国外的github
自建的私有仓库,gitlab
都是远程仓库



如果你想获取github上的代码,或者你公司gitlab私有仓库的代码,可以使用git clone命令,下载克隆远程仓库的代码。

git clone https://github.com/django/django.git

下载出来的代码已经是被git管理的本地仓库

你会发现所有的项目文件都在这里,等待后续开发

9.5 了解.git目录原理

[root@pyyuc ~/git_learning/mysite 11:08:19]#tree .git
.git
├── branches
├── config    这个项目独有的配置
├── description
├── HEAD    head文件指示目前被检出的分支
├── hooks  hooks目录包含服务端和客户端的钩子脚本 hook scripts
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── index  index文件保存暂存区的信息,只有git add之后才会生成,默认还没有这个文件
├── info    info目录是全局性排除文件,用于放置不想被记录在.gitignore文件中的忽略模式(ignored patterns)
│   └── exclude
├── objects  存储所有数据内容
│   ├── info
│   └── pack
└── refs  refs目录存储指向数据(分支)的提交对象的指针
    ├── heads
    └── tags

.git文件夹解析

10.图解git工作流

git实现本地版本控制系统,设计三大分区

workspace                               工作区(某文件夹)

Index/Stage/Cached               暂存区

Repository                                本地仓库

Remote Repository                 远程仓库(gitlab、github)

git的操控命令,就是在这四大工作区,来回切换的!!
还记得git的四个区域吗?本地文件夹,暂存区,本地仓库,远程仓库吗?

本地文件夹未初始化时,git是不认识的

本地文件夹 git init后,就成了git local repo 本地仓库

请记住,在工作文件夹的每一个文件,只有两种状态,一个是未跟踪,一个是已跟踪

已跟踪的指的是已经被纳入git版本管理的文件,在git快照中有他的记录

执行git add . 表示添加所有未被git跟踪的文件,用git进行跟踪状态

image-20220706171639372


image-20220706172350543

11.git命令实践

11.1 从零初始化git本地仓库

https://git-scm.com/docs/git-init/zh_HANS-CN

该命令创建一个空的Git存储库 - 本质上是一个 .git 目录


# 1. 创建工作区,且初始化一个git本地仓库,文件夹叫做learn_git


[root@www.yuchaoit.cn ~]#mkdir -p /home/yuchao/ && cd /home/yuchao/
[root@www.yuchaoit.cn /home/yuchao]#
[root@www.yuchaoit.cn /home/yuchao]#
[root@www.yuchaoit.cn /home/yuchao]#
[root@www.yuchaoit.cn /home/yuchao]#git init learn_git
Initialized empty Git repository in /home/yuchao/learn_git/.git/
[root@www.yuchaoit.cn /home/yuchao]#
[root@www.yuchaoit.cn /home/yuchao]#tree
.
└── learn_git

1 directory, 0 files

11.2 查看暂存区

暂存区(stage或index): 也叫缓存区

暂存区就看作是一个缓区区域,临时保存你的改动。

如果在工作目录创建了一个新文件,需要将新文件添加到暂存区。

创建新文件,添加到暂存区

# 1. 生成新文件

[root@www.yuchaoit.cn /home/yuchao]## 进入到本地仓库
[root@www.yuchaoit.cn /home/yuchao]#cd /home/yuchao/learn_git
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]## 此时这个文件还未被git管理
[root@www.yuchaoit.cn /home/yuchao/learn_git]#echo "加油努力干,攒钱买房买车娶媳妇!!" >  jiayou.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]## 查看文件状态
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    jiayou.sh
nothing added to commit but untracked files present (use "git add" to track)

此时该文件,是还未被跟踪的状态


使用git add命令,提交该文件到暂存区,且进行跟踪(逆向操作,git rm --cached jiayou.sh )

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git add jiayou.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   jiayou.sh
#


此时查看.git文件夹中多了一个index文件,就是暂存区文件
[root@www.yuchaoit.cn /home/yuchao/learn_git]#file .git/index
.git/index: Git index, version 2, 1 entries


可以用strings命令查看该文件数据,已经记录了jiayou.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#strings .git/index
DIRC
O?Cb
    jiayou.sh

11.3 从暂存区移除文件

[root@www.yuchaoit.cn /home/yuchao/learn_git]#echo "坚持下去,才会开花结果!!" >> jianchi.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git add .
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#strings .git/index
DIRC
!gLb
jianchi.sh
O?Cb
    jiayou.sh
Daw)


从暂存区移除该俩2文件的记录,也就是取消用git去跟踪管理

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   jianchi.sh
#    new file:   jiayou.sh



[root@www.yuchaoit.cn /home/yuchao/learn_git]#git rm --cached jia*
rm 'jianchi.sh'
rm 'jiayou.sh'
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    jianchi.sh
#    jiayou.sh
nothing added to commit but untracked files present (use "git add" to track)


再次查看index暂存区信息

[root@www.yuchaoit.cn /home/yuchao/learn_git]#strings .git/index
DIRC

11.4 重新跟踪、提交文件

[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    jianchi.sh
#    jiayou.sh
nothing added to commit but untracked files present (use "git add" to track)
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#

# 提交文件从工作区  > 暂存区,进行git跟踪状态

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git add .

11.5 查看文件状态

git status 命令可以查看工作区里有哪些文件需要被提交,以及是否被git跟踪

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   jianchi.sh
#    new file:   jiayou.sh
#

11.6 基于git的文件重命名

目前我们已经发现,在git的工作区中操作,会有2个状态

1是未被git追踪的文件
2是被git追踪的文件(记录到暂存区了)

那么你如果直接修改文件名,就得注意,是否被git追踪了,以及如何正确的玩法。

错误玩法

用mv去改,你会发现这原本被git追踪的文件jiayou.sh

通过mv改名,git其实是先删除了该文件,然后又重新创建了未被git跟踪的文件jiayou2.sh

但是别忘了jiayou.sh 还在index暂存区中。。。我擦,这咋整?

所以在git本地仓库中的操作,还是需要一定理解的。

执行如下2个操作

  • 删除暂存区中的jiayou.sh
  • 添加jiayou2.sh到暂存区
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git rm --cached jiayou.sh
rm 'jiayou.sh'
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   jianchi.sh
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    jiayou2.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git add jiayou2.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   jianchi.sh
#    new file:   jiayou2.sh
#

现在这俩文件,都已经在暂存区,等待commit 提交到 local repo了。

正确玩法

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git mv jiayou2.sh jiajiayou.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   jiajiayou.sh
#    new file:   jianchi.sh
#

11.7 基于git的删除文件

错误删除

暂存区里现在有俩文件数据
[root@www.yuchaoit.cn /home/yuchao/learn_git]#ll
total 8
-rw-r--r-- 1 root root 52 Jul  6 18:11 jiajiayou.sh
-rw-r--r-- 1 root root 40 Jul  6 18:11 jianchi.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   jiajiayou.sh
#    new file:   jianchi.sh
#


直接rm删除试试?

[root@www.yuchaoit.cn /home/yuchao/learn_git]#rm -rf jia*
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#ls
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   jiajiayou.sh
#    new file:   jianchi.sh
#
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#    deleted:    jiajiayou.sh
#    deleted:    jianchi.sh

这俩文件,只要还存在暂存区,就可以恢复
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git checkout -- jia*
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#ls
jiajiayou.sh  jianchi.sh

正确删除

也就是,这个文件,的确不想要了,从暂存区移除追踪记录
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git rm --cached jia*
rm 'jiajiayou.sh'
rm 'jianchi.sh'
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#ll
total 8
-rw-r--r-- 1 root root 52 Jul  6 18:13 jiajiayou.sh
-rw-r--r-- 1 root root 40 Jul  6 18:13 jianchi.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    jiajiayou.sh
#    jianchi.sh
nothing added to commit but untracked files present (use "git add" to track)
[root@www.yuchaoit.cn /home/yuchao/learn_git]#



此时再删除,就彻底没了


[root@www.yuchaoit.cn /home/yuchao/learn_git]#rm -f jia*
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#ls

11.8 提交暂存区数据到local repo

练一练,完整的提交版本记录的操作

image-20220706181554951

提交v1版本

我们目前,都只是在 工作区,和暂存区 进行玩耍


git commit 可以提交暂存区的临时数据,放入local repo,提交为第一个版本



[root@www.yuchaoit.cn /home/yuchao/learn_git]#echo '加油啊兄弟们,胜利的曙光就要看到了!!' > laoliu.sh

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    laoliu.sh
nothing added to commit but untracked files present (use "git add" to track)


[root@www.yuchaoit.cn /home/yuchao/learn_git]#git add .
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   laoliu.sh
#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git commit -m 'first commit with line 1'
[master (root-commit) fb118ba] first commit with line 1
 1 file changed, 1 insertion(+)
 create mode 100644 laoliu.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git log
commit fb118ba9639431c32f1a1f22bff8e4b0ddaac1cb
Author: pyyu <yc_uuu@163.com>
Date:   Wed Jul 6 18:40:02 2022 +0800

    first commit with line 1


此时再用git status啥也看不到了,干净的工作区
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
nothing to commit, working directory clean

提交v2版本

[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat laoliu.sh
加油啊兄弟们,胜利的曙光就要看到了!!
好的超哥,我一定相信自己,加油努力,给自己一个满意的结果!!


git已经发现文件内容被修改了


[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#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:   laoliu.sh
#
no changes added to commit (use "git add" and/or "git commit -a")

用git diff看看文件内容区别

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git diff laoliu.sh
diff --git a/laoliu.sh b/laoliu.sh
index 5018c92..b736bb6 100644
--- a/laoliu.sh
+++ b/laoliu.sh
@@ -1 +1,2 @@
 加油啊兄弟们,胜利的曙光就要看到了!!
+好的超哥,我一定相信自己,加油努力,给自己一个满意的结果!!

+号开头,表示这一行是新增的内容

提交v2版本,提交第二个commit记录,每一次commit 都会有id记录

记住,先git add,提交到暂存区,然后再commit,到本地仓库

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git add .
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#    modified:   laoliu.sh
#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git commit -m 'v2 添加了第二行数据'
[master 9a3bd4d] v2 添加了第二行数据
 1 file changed, 1 insertion(+)
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git log
commit 9a3bd4d40480749247e4c784a24fb13cb0fb0120
Author: pyyu <yc_uuu@163.com>
Date:   Wed Jul 6 18:46:34 2022 +0800

    v2 添加了第二行数据

commit fb118ba9639431c32f1a1f22bff8e4b0ddaac1cb
Author: pyyu <yc_uuu@163.com>
Date:   Wed Jul 6 18:40:02 2022 +0800

    first commit with line 1

因此,通过 git log 可以查看到每一次的提交记录。

提交v3版本

[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat laoliu.sh
加油啊兄弟们,胜利的曙光就要看到了!!
好的超哥,我一定相信自己,加油努力,给自己一个满意的结果!!

兄弟们,git工具,一般是开发人员用的多,我们运维一般也就是上传,下载代码而已了。


[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#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:   laoliu.sh
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@www.yuchaoit.cn /home/yuchao/learn_git]#


添加,提交
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git commit -m 'v3 就玩三次吧'
[master e9547df] v3 就玩三次吧
 1 file changed, 2 insertions(+)
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git status
# On branch master
nothing to commit, working directory clean
[root@www.yuchaoit.cn /home/yuchao/learn_git]#

git命令小结

1. 创建文件数据
2. git add 文件名  追踪文件,添加到暂存区
3. git status 查看工作区的文件状态
4. git diff 文件名  查看文件修改的对比情况
5. git commit -m '提交注释'  提交暂存区的内容到本地仓库
6. 结束第一次版本提交
7. 多次commit 提交,就存在了多次版本记录,git 可以实现版本回退功能

12.git版本历史

在我们使用git的时候,会对代码文件不停的修改,不断的提交到代码仓库。

这个就如同我们打游戏时候,保存关卡记录的操作。

image-20200706162827184

在打boss之前,先做一个存档,防止你这个渣渣,被boss一招秒杀,又得从头再来。。。。。

因此被boss弄死,可以从存档,重新开始游戏。。。。

12.1 git log

当你的代码写好了一部分功能,就可以保存一个"存档",这个存档操作就是git commit,如果代码出错,可以随时回到"存档"记录

查看"存档"记录,查看commit提交记录的命令 git log

我们可以吧git commit操作与虚拟机的快照做对比理解,简单理解就是每次commit,就等于我们对代码仓库做了一个快照。

可以演示下vmware快照

那么我们如何知道文件快照了多少次呢?

git log命令显示,从最新的commit记录到最远的记录顺序。

git log --oneline    一行显示git记录
git log --oneline  --all  一行显示所有分支git记录
git log --oneline --all -4 --graph 显示所有分支的版本演进的最近4条
git log -4  显示最近4条记录
git log --all     显示所有分支的commit信息



git branch -v 查看分支信息

git help --web log 以浏览器界面显示log的参数

12.2 查看提交版本历史

1, 使用git log查看提交的历史版本信息

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git log
commit e9547dfc7aa124564bb962031b08053d127d5d6b
Author: pyyu <yc_uuu@163.com>
Date:   Wed Jul 6 18:49:34 2022 +0800

    v3 就玩三次吧

commit 9a3bd4d40480749247e4c784a24fb13cb0fb0120
Author: pyyu <yc_uuu@163.com>
Date:   Wed Jul 6 18:46:34 2022 +0800

    v2 添加了第二行数据

commit fb118ba9639431c32f1a1f22bff8e4b0ddaac1cb
Author: pyyu <yc_uuu@163.com>
Date:   Wed Jul 6 18:40:02 2022 +0800

    first commit with line 1



[root@www.yuchaoit.cn /home/yuchao/learn_git]#git log --oneline
e9547df v3 就玩三次吧
9a3bd4d v2 添加了第二行数据
fb118ba first commit with line 1



查看最新2条日志
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git log -2 --oneline
e9547df v3 就玩三次吧
9a3bd4d v2 添加了第二行数据


前面的字符串,就是commit 版本提交记录ID

12.3 git版本回退

学到这里,超哥想起来那年十八岁,听着周董的《回到过去》。。

image-20200706174453642

我们已知git commit可以提交代码到本地仓库,如同虚拟机的快照,当也可以进行版本回退。

git log可以查看历史版本记录
git reset --hard命令可以回退版本
git reset --hard HEAD^ 回退到上个版本
HEAD表示当前版版本
HEAD^  表示上1个版本
HEAD^^ 上2个版本

也可以直接git reset --hard 版本id号

这个时候就发现,git commit -m 所标记的注释信息非常重要了吧,可以让你自己知道到底回退到什么版本

回退上一个版本,回到v2

[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat laoliu.sh
加油啊兄弟们,胜利的曙光就要看到了!!
好的超哥,我一定相信自己,加油努力,给自己一个满意的结果!!

兄弟们,git工具,一般是开发人员用的多,我们运维一般也就是上传,下载代码而已了。


[root@www.yuchaoit.cn /home/yuchao/learn_git]#git reset --hard HEAD^
HEAD is now at 9a3bd4d v2 添加了第二行数据
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat laoliu.sh
加油啊兄弟们,胜利的曙光就要看到了!!
好的超哥,我一定相信自己,加油努力,给自己一个满意的结果!!

再回到第一个v1版本

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git reset --hard HEAD^
HEAD is now at fb118ba first commit with line 1

[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat laoliu.sh
加油啊兄弟们,胜利的曙光就要看到了!!

我还想回到v3版本咋办

git reflog可以看到所有的git操作历史,也就可以看到commit版本记录的id了。

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git reflog
fb118ba HEAD@{0}: reset: moving to HEAD^
9a3bd4d HEAD@{1}: reset: moving to HEAD^
e9547df HEAD@{2}: commit: v3 就玩三次吧
9a3bd4d HEAD@{3}: commit: v2 添加了第二行数据
fb118ba HEAD@{4}: commit (initial): first commit with line 1

回到v3版本,基于commit即可

[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat laoliu.sh
加油啊兄弟们,胜利的曙光就要看到了!!
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git reflog
fb118ba HEAD@{0}: reset: moving to HEAD^
9a3bd4d HEAD@{1}: reset: moving to HEAD^
e9547df HEAD@{2}: commit: v3 就玩三次吧
9a3bd4d HEAD@{3}: commit: v2 添加了第二行数据
fb118ba HEAD@{4}: commit (initial): first commit with line 1
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git reset --hard e9547df
HEAD is now at e9547df v3 就玩三次吧
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git reflog
e9547df HEAD@{0}: reset: moving to e9547df
fb118ba HEAD@{1}: reset: moving to HEAD^
9a3bd4d HEAD@{2}: reset: moving to HEAD^
e9547df HEAD@{3}: commit: v3 就玩三次吧
9a3bd4d HEAD@{4}: commit: v2 添加了第二行数据
fb118ba HEAD@{5}: commit (initial): first commit with line 1
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git log --oneline
e9547df v3 就玩三次吧
9a3bd4d v2 添加了第二行数据
fb118ba first commit with line 1
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#



[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat laoliu.sh
加油啊兄弟们,胜利的曙光就要看到了!!
好的超哥,我一定相信自己,加油努力,给自己一个满意的结果!!

兄弟们,git工具,一般是开发人员用的多,我们运维一般也就是上传,下载代码而已了。

12.4 git log总结

git log 原理图

image-20200706174930054

  • 提交后的代码文件,使用git log查看当前版本及以前的历史版本。
  • 使用git reset --hard HEAD^或者git reset --hard HEAD^^实现版本回退。
  • 使用git reflog查看提交的所有操作及版本号
  • 使用git reset --hard 版本号你可以自由的在不同版本之间来回切换。

git版本控制不仅仅是用于项目开发,你也可以用于一个软件包仓库的版本控制。

也可以是你电脑的资料管理,只要是文件就可以管理。

13.git撤销功能

今天于超老师写代码时,心情不太好,写了一堆bug,咋整?

有没有后悔药?有 git checkout命令

写代码搞起

[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat hello.sh
echo "练一练git撤销命令?"
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git add .
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#git commit -m 'v1 hello.sh'
[master 049a22f] v1 hello.sh
 1 file changed, 1 insertion(+)
 create mode 100644 hello.sh

故意写错

[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat hello.sh
echo "练一练git撤销命令?"
你瞅啥?给你邦邦两拳!



[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#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:   hello.sh
#
no changes added to commit (use "git add" and/or "git commit -a")

撤销的多种情况

  • 直接删除就行,但是如果内容太多,你摸不清发生啥了呢?就没办法了

  • 使用git checkout -- 文件名就可以直接撤销修改了

  • 如果写乱了代码,添加暂存区但还没有commit提交。使用git reset HEAD 文件名取消暂存区添加,再git checkout -- 文件名来撤销修改

  • 如果写乱了代码,添加暂存区并提交了。则使用版本回退

我们这里,还未添加到暂存区,直接撤销

[root@www.yuchaoit.cn /home/yuchao/learn_git]#git checkout -- hello.sh
[root@www.yuchaoit.cn /home/yuchao/learn_git]#
[root@www.yuchaoit.cn /home/yuchao/learn_git]#cat hello.sh
echo "练一练git撤销命令?"

14.git版本控制总结

image-20220706195415384

Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 wechat: laoyuer1993 2025-05-13 16:32:20

results matching ""

    No results matching ""