Git的基本操作和原理

目录

写在前面的话        

为什么要有Git(git初识)?

Git安装(Centos为例)

Git基本操作

创建Git本地仓库

Git配置

认识工作区、暂存区、版本库

概念认识

添加文件

查看.git文件

修改文件

版本回退

撤销修改

情况一:对于工作区的代码,还没有 add

情况二:已经 add ,但没有 commit

情况三:已经 add ,并且也 commit 了

删除文件


 

写在前面的话        

        没实习前接触过git,但是一直没在意,心里想git不就是远端存储代码吗,我到时候直接在平台上把文件手动上传上去也可以啊,何必大费周章学这么多git知识,那么麻烦。

        自从前两个月实习后,才意识到git在企业中是多么的重要,几乎所有的工作都在git的基础上进行的,也意识到git是多么的强大。包括后面才知道的版本控制,分支管理,多人协作等等。比如其他同事代码有问题,我可以直接一条命令切换到这个同事的分支上,便可以看到该同事所写的代码;以及完成某个任务时,内容需要不断的修改,每个版本间的改动等等,都可以直接切换且管理起来,特别厉害。

        所以同学们还是尽量早点学会git好,当初进去的时候对git一点都不理解,也耗费了挺长时间进行学习,走了挺多弯路,经过不断的学习,对git略有了解了,所以在此系统记录一下git的使用和原理.

为什么要有Git(git初识)?

        在我们大学学习的时候,,有没有遇到这样的情况:我们在编写各种⽂档时,为了防⽌⽂档丢失,更改失误,失误后能恢复到原来的版本,为此不得不复制出⼀个副本,然后在这个副本的基础上进行改动,避免 改了半天改错了,原来的版本也恢复不回去了。

“报告-v1”
“报告-v2”
“报告-v3”
“报告-确定版”
“报告-最终版”

每个版本有各⾃的内容,但最终会只有⼀份报告需要被我们使⽤。

但在此之前的⼯作都需要这些不同版本的报告,于是每次都是复制粘贴副本,产出的⽂件就越来越多,⽂件多不是问题,问题是:随着版本数量的不断增多,你还记得这些版本各⾃都是修改了什么

⽂档如此,我们写的项⽬代码,也是存在这个问题的!

那如何解决呢?

这就用到了版本控制器:为了能够更⽅便我们管理这些不同版本的⽂件,便有了版本控制器。所谓的版本控制器,就是能让你 了解到⼀个⽂件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统,同时也⽅便多⼈协同作业。

⽬前最主流的版本控制器就是Git。Git可以控制电脑上所有格式的⽂件,例如doc、excel、dwg、dgn、rvt等等。

Git安装(Centos为例)

这里git的安装操作只简单介绍一下Linux下centos的安装过程,安装不是我要说的重点。像在Windows,MAC或Ubuntu等系统下的安装,可以去b站或网上搜索相关教程.

1. 首先在命令行输入git,来看有没有安装git,若没有,系统则会弹出如下警告:

$ git
-bash: git: command not found

若你已经安装,则会弹出git的相关使用方法.

2.安装git

sudo yum -y install git

3.查看git 版本 

git --version 

若是有对应的版本,则说明已经安装成功:

Git基本操作

创建Git本地仓库

        首先提前说一下,我们既然要对某个文件进行版本控制,那么该文件位置一定是特定的。如果该文件位置是随意的,那么git该如何跟踪 它的修改呢?显然是不可能的.

        所以需要跟踪修改的文件 一定要位于Git仓库中,这样git才能跟踪修改。

        那么如何初始化呢?

首先,仓库是进⾏版本控制的⼀个文件目录,所以我们要先创建一个目录,我命名为gitnode,然后进入该目录,使用以下命令初始化仓库:

git init

 此时我们的目录下面会多出来一个隐藏文件:.git文件,是用来进行版本控制和跟踪改动的。千万不要随意修改.git文件下的任何内容:

这样一个git仓库便创建好了.(注意:git仓库(又叫版本库)是指.git这个目录,而不是创建的gitnode这个目录!后面会细说)

Git配置

当安装Git后⾸先要做的事情是设置你的 用户名称和e-mail地址 ,这是⾮常重要的。配置命令为:

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

其中:

# 把 Your Name 改成你的昵称
# 把 email@example.com 改成邮箱的格式,只要格式正确即可

# [--global]可以先不加,等下说明作用。

配置完成后,可以使用以下命令查看自己的配置:

git config -l

 注意到刚才的命令有个 --global 选项,这个选项的作用是什么呢?

首先我们要知道,我们不仅仅只有一个git仓库,而是可以有多个git仓库,加上--global(注意不要加[])可以让改配置在所有的git仓库中生效,而不只是当前git仓库.

如果我们想删除配置项,可以使用如下指令:

1.删除某个仓库中的配置:

git config --unset user.name
git config --unset user.email

2.删除所有仓库中的配置

git config --global --unset user.name
git config --global --unset user.email

认识工作区、暂存区、版本库

概念认识

当我们在gitnode目录下创建一个文件ReadMe,这个文件是否被git管理了呢?

答案是否定的.我们真正的git仓库是在.git文件中的,我们需要将文件添加到.git文件中才能被进行管理。

此时当前这个gitnode目录叫做工作区,即在电脑上要写代码或文件的目录。

而.git文件被称为版本库,也就是我们一开始说的仓库。但它不属于工作区,⽽是Git的版本库。

这个版本库里面的所有文件都可以被Git管理起来,每个文件的修改、删除 ,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

我们具体来看一下他们的关系:

版本库中有stage暂存区和右边的master分支等,至于这个master分支,我们先不用管,后面我会详细介绍。

也就是我们在工作区中的修改(包括新增的文件,对文件内容的修改,删除的文件)等,都要先add到 版本库中的stage(又叫暂存区或索引)中,然后再commit到分支上。这样文件才真正意义上被git管理起来了,这是目前的流程.

这里再补充一点:git之所以轻量化,是因为在版本库中,有一个名为objects的对象库,所有修改的工作区内容都会写入objects对象库中的一个新git对象中,而每个文件正存放的是这些一个个git对象,相当于只是存放了改动,没有存放全部代码。

添加文件

我们刚才说了基本的概念和流程,但具体每一步如何做,我们还没有说,接下来我们将讲解它.

首先我们在工作区中的ReadMe文件添加一行hello,world,然后我们使用git add指令将其添加到暂存区中:

有以下三种方式:

  • 添加⼀个或多个文件到暂存区:
git add [file1] [file2] ...

  •  添加指定目录到暂存区,包括子目录:
 git add [dir]

  • 添加当前目录下的所有⽂件改动到暂存区:
git add .

当然git add + 指定路径下文件都可以.

将其添加到暂存区中之后,我们需要使用git commit 指令将暂存区内容添加到指定仓库中:

  • 提交暂存区全部内容到本地仓库中:
 git commit -m "message" 

  • 提交暂存区的指定⽂件到仓库区:
 git commit [file1] [file2] ... -m "message"

其中message一定要写,写上你本次对该文件的改动,这是给我们其他同事看的,方便知道你此次对该文件做了哪些改动与处理.

可以看到已经被管理起来了,一个文件被改动(新建的文件ReadMe),1次插入(新增了一行"hello world").

假设此时我们又新增了一个文件file,并且不做任何修改:

可以发现一个文件被改动,然后没有任何的插入和删除。

这里再告诉大家一个命令,叫做

git log

该指令可以查看所有的git 提交记录,如下:

我之前两次的提交记录都显示了出来,这便是git log的作用

查看.git文件

在进行了这两次提交操作后,.git文件中有哪些变化呢?

这是我一开始没有进行任何提交时的.git目录:

这是当我提交完两次之后的.git目录图:

我们首先可以看一下HEAD文件中有什么:

它指向了.git目录下的refs/heads/master文件,那我们查看一下该文件里面有什么:

是这一串commit id,反过来我们再来看一下我们的提交时的commit id: 

可以发现正好是我们最新一次的提交的commit id,也就是说HEAD指针指向了我们最新一次的提交,当然objects中使我们每一次的改动,我这里也不查看了。

总结⼀下,在本地的git仓库中,有⼏个⽂件或者⽬录很特殊

  •  index:暂存区, git add 后会更新该内容。
  •  HEAD:默认指向master分⽀的⼀个指针。
  •  refs/heads/master:⽂件⾥保存当前 master 分⽀的最新 commit id 。
  •  objects:包含了创建的各种版本库对象及内容,可以简单理解为放了git维护的所有修改。 

修改文件

        Git⽐其他版本控制系统设计得优秀,因为Git 跟踪并管理的是修改而非文件。
什么是修改?⽐如你新增了⼀⾏,这就是⼀个修改;删除了⼀⾏,也是⼀个修改;更改了某些字符,也是⼀个修改;删了⼀些⼜加了⼀些,也是⼀个修改;甚⾄创建⼀个新⽂件,也算⼀个修改。

        我们在ReadMe文件中,添加如下几行:

保存退出后,我们使用

git status

来查看当前文件的状态:

 可以发现,它告诉我改动还没有暂存起来提交,也就是还没有添加到暂存区,第二个红框告诉我们修改的文件是ReadMe.

但是它只告诉了我们哪个文件被修改了,没告诉我具体有哪些改动,我们该如何查看呢?

可以使用

git diff [file]

查看暂存区和工作区文件的差异,显⽰的格式正是Unix通⽤的diff格式.

如下:

我来解释一下@@ -1 +1 4 @@什么意思

-1表示改动前的第一行 是hello,world

+1 4 表示改动后的从第一行开始的后4行(如图所示的那四行).后面的3行前面的+代表是新插入的.

回到刚才所说的,git status,此时当我们add到暂存区后,再次查看状态:

此时告诉我们将要被提交,意思是添加到工作区中了,需要commit.

当我们commit后:

 它此时告诉我们没有可以提交的了。工作目录是空的,至此我们也算提交完成了.

版本回退

之前我们也提到过,Git能够管理⽂件的历史版本,这也是版本控制器重要的能⼒。如果有⼀天你发现当前的⼯作做的出现了很⼤的问题,需要从某个特定的历史版本重新开始,这个时候,就需要版本回退的功能了。
执⾏ git reset 命令⽤于回退版本,可以指定退回某⼀次提交的版本。要解释⼀下“回退”本质是
要将版本库中的内容进⾏回退,⼯作区或暂存区是否回退由命令参数决定:

git reset [--soft | --mixed | --hard] [HEAD]
  • --soft 参数对于⼯作区和暂存区的内容都不变只将版本库回退到某个指定版本。
  • --mixed 为默认选项,使⽤时可以不⽤带该参数。该参数对于⼯作区⽂件保持不变,将暂存区和版本库内容退回为指定提交版本内容,
  • --hard 参数将暂存区、⼯作区和版本库都退回到指定版本。切记⼯作区有未提交的代码时不要⽤这个命令,因为⼯作区会回滚,你没有提交的代码就再也找不回了,所以使⽤该参数前⼀定要慎重。

可以看这个表格进行区分:

 我们先添加了git,后添加的world,使用三个选项后会导致的结果都显示了出来.

HEAD参数可以如下使用:

HEAD 说明:
◦ 可直接写成commit id,表⽰指定退回的版本
◦ HEAD 表⽰当前版本
◦ HEAD^ 上⼀个版本
◦ HEAD^^ 上上⼀个版本
◦ 以此类推...


• 可以使用~数字表示
◦ HEAD~0 表⽰当前版本
◦ HEAD~1 上⼀个版本
◦ HEAD^2 上上⼀个版本 
◦ 以此类推...


那我们来使用一下git reset.

先来看一下我这三次版本的改动.

我现在如果想回退到第二个版本,那么ReadMe文件中新插入的三行内容应该会消失:

我们使用git reset --hard 第二个版本的commit id 进行回退

 

可以发现第三个版本的内容确实没了,但是我如果后悔了,想重新回到第三个版本该怎么办呢?

git log查看下所有commit id? 我们试试:

可以发现我们只有两次提交的commit id,第三次的已经没有了,那么该如何恢复呢?

这里我们用到了如下命令:

git reflog

我们可以通过使用git reflog命令,就可查看到所有历史版本信息。由于查看所有历史版本信息的目的,大多是为了进行版本回退或恢复操作所使用,从中找到所需的commit索引,所以该命令被命名为reflog,即:引用日志。

这样我们便可以 再次通过git reset来恢复了:

此时我们发现,我们又回到了第三个版本,ReadMe中的内容也全部恢复了. 

git log 和 git reflog的关系如下:

图片来源于简书:繁华似锦Fighting

撤销修改

如果我们在我们的⼯作区写了很长时间代码,越写越写不下去,觉得自己写的实在是垃圾,想恢复到上⼀个版本,该如何做呢?

情况一:对于工作区的代码,还没有 add

两种方式:

1.自己手动删除写的代码(但是如果写了很长时间,哪些代码是新增的,哪些删除了,我们不会记得非常清晰,很容易出错,因此不建议)

2.使用 git checkout -- [file]命令撤销当前工作区更改

可以发现使用该指令后,原来工作区中的代码改动被撤销了.

情况二:已经 add ,但没有 commit

 此时我们需要将暂存区中的内容和工作区中的内容全部撤销回到上一个版本.该如何做呢?

        我们来回忆⼀下刚讲过的 git reset 回退命令,该命令如果使⽤ --mixed 参数,可以将暂存区
的内容退回为指定的版本内容
,但⼯作区⽂件保持不变。那我们就可以回退下暂存区的内容了!

这样暂存区中的代码就已经被撤销了,但是还有工作区中的代码没有被撤销,那我们可以按照刚才的方法,使用 git checkout -- [file]命令撤销当前工作区更改。

两个方法组合起来便将暂存区和工作区中的修改全部撤销了.

综上,使用这两句命令便可完成操作:

git reset --mixed HEAD
git checkout -- [file]

或者直接干脆点,将选项改为hard,将工作区、暂存区、版本库全部回退到当前版本,因为此时还没有commit ,所以版本库还是原来的不变,工作区和暂存区全部回退到了和当前版本库一样的代码.

情况三:已经 add ,并且也 commit 了

这个情况适用于comomit但还没有push到远端仓库时的代码,至于远端仓库,后面会说。

同样地我们只需要git reset --hard HEAD^ 即回退到上一个版本,所有的内容工作区和暂存区及版本库也全部回到上一个版本了.

这便是所有情况的一个总结了,xxx code为新增的代码以及所处的位置:

删除文件

当我们想删除一个文件时,我们可以有两种方法可以删除:

1.按正常的流程,删除文件后,add到暂存区,然后commit

2.使用git提供的指令来删除,然后commit提交

第一种方法我就不演示了,直接说第二种方法:

git提供的删除指令是

git rm

例如我们想删除file文件,git rm会讲文件从工作区和暂存区中删除(第一种普通的rm删除只会删除工作区的文件,因此需要add和commit),但版本库中还没有删除,因此还需要commit一次,如下:

至此,关于git的基本操作就完成了 ,感谢您的阅读,若是有不理解或疑问的地方,欢迎评论区留言哦~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[数据集][目标检测]游泳者溺水数据集VOC+YOLO格式2类别895张

数据集制作单位:未来自主研究中心(FIRC) 数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):895 标注数量(xml文件个数)&#xff1a…

博途PLC PID仿真(单容水箱液位高度控制含变积分变增益测试)

单容水箱和双荣水箱的微分方程和数值求解,可以参考下面文章链接: https://rxxw-control.blog.csdn.net/article/details/131139432https://rxxw-control.blog.csdn.net/article/details/131139432这篇博客我们利用欧拉求解器在PLC里完成单容水箱的数学建模。PLC也可以和MATL…

SpringBoot Admin 详解

SpringBoot Admin 详解 一、Actuator 详解1.Actuator原生端点1.1 监控检查端点:health1.2 应用信息端点:info1.3 http调用记录端点:httptrace1.4 堆栈信息端点:heapdump1.5 线程信息端点:threaddump1.6 获取全量Bean的…

基于SSM的萌宠宜家商城系统(有报告)。Javaee项目。ssm项目。

演示视频: 基于SSM的萌宠宜家商城系统(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring …

【黑马程序员】3、TypeScript常用类型_黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程

课程地址:【黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程】 https://www.bilibili.com/video/BV14Z4y1u7pi/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 3、TypeScript常用类型 3.1 类型注解 …

【51单片机】想学会串口通信,你需要知道这些(串口通信实验前置知识)(13)

前言 大家好吖,欢迎来到 YY 滴单片机系列 ,热烈欢迎! 本章主要内容面向接触过单片机的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的…

Qt Android sdk配置报错解决

使用的jdk8总是失败,报错command tools run以及platform sdk等问题。后来主要是设置jdk版本为17,就配置生效了。Android sdk路径可以选用Android Studio自带的,但是也要在Qt中点击“设置SDK”按钮做必要的下载更新等。 编译器这里会自动检测到…

【黑马程序员】2、TypeScript介绍_黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程

课程地址:【黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程】 https://www.bilibili.com/video/BV14Z4y1u7pi/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 2、TypeScript初体验 2.1 安装编译TS的工…

探究全链路压力测试的含义与重要性

全链路压力测试是指对整个应用系统的各个环节或组件进行压力测试,以模拟实际生产环境中的用户负载和流量,评估系统在高负载条件下的性能表现。 1. 全链路压力测试的含义 全链路压力测试涉及系统的所有组件和环节,包括前端用户界面、应用服务器…

算法沉淀——动态规划之路径问题(leetcode真题剖析)

算法沉淀——动态规划之路径问题 01.不同路径02.不同路径 II03.珠宝的最高价值04.下降路径最小和05.最小路径和06.地下城游戏 01.不同路径 题目链接:https://leetcode.cn/problems/unique-paths/ 一个机器人位于一个 m x n 网格的左上角 (起始点在下图…

c++: 用c++语言对车辆进行建模

一 原理 1.1 阿克曼转向模型 转向半径:后轴中心点到原点O的距离 已知道转向半径,可以反求转向角。或者知道转向角,可以求出转向半径。 四个顶点的转向半径。 还要定义这两个参数 1.2 车辆运动的建模 运动写在大的while循环里。 绘制车辆的思路;(1)清

020 基于Spring Boot + Thymeleaf 实现的任务发布网站(源码+数据库)

部分代码地址: https://github.com/XinChennn/xc020-springboot-recruit 基于Spring Boot Thymeleaf 实现的任务发布网站(源码数据库) 一、系统介绍 雇主:登录、注册、发布任务、选择中标雇员、评价雇员雇员:登录、…

如何解决Nginx启动出现闪退问题?

哈喽,大家好,我是小浪。那么大家首次在启动nginx的时候,绝大部分同学会出现以下情况,就是我们双击nginx.exe文件之后,屏幕闪退一下就没了,然后我们访问localhost:8080提示404. 那么出现这种情况其实是我们…

【深度学习笔记】 3_13 丢弃法

注:本文为《动手学深度学习》开源内容,部分标注了个人理解,仅为个人学习记录,无抄袭搬运意图 3.13 丢弃法 除了前一节介绍的权重衰减以外,深度学习模型常常使用丢弃法(dropout)[1] 来应对过拟合…

“点击查看显示全文”遇到的超链接默认访问的问题

今天在做一个例子,就是很常见的点击展开全文。 我觉得这是一个很简单的效果,也就几行代码的事,结果点击了以后立刻隐藏不见,控制台代码也不报错,耽误了我很长时间,最后才发现问题出在超链接身上。 “展开全…

k8s-kubeapps部署 20

部署kubeapps应用,为Helm提供web UI界面管理: 下载最新版本的kubeapps并修改其values.yaml文件 下载并拉取所需镜像: 部署应用 添加解析 修改svc暴露方式为LoadBalancer 得到分配地址 访问http://192.168.182.102 授权并获取token 1.24前的…

osmnx笔记:从OpenStreetMap中提取点和边的shp文件(FMM文件准备内容)

1 导入库 import osmnx as ox import time from shapely.geometry import Polygon import os import numpy as np 2 提取Openstreetmap 的graph Gox.graph_from_place(Huangpu,Shanghai,China,network_typedrive,simplifyTrue) ox.plot_graph(G) 3 提取graph中的点和边 gdf…

pytest如何在类的方法之间共享变量?

在pytest中,setup_class是一个特殊的方法,它用于在类级别的测试开始之前设置一些初始化的状态。这个方法会在类中的任何测试方法执行之前只运行一次。 当你在setup_class中使用self来修改类属性时,你实际上是在修改类的一个实例属性。在Pyth…

《模仿游戏》:天才团队如何破解密码学之谜

引言 计算机科学相关的电影不少,有探索人工智能的《黑客帝国》、还有逻辑和结构学的《盗梦空间》、还有互联网创业的《社交网络》和《硅谷海盗》、还有探索虚拟世界的《源代码》,更甚有国产计算机科学科幻启蒙儿童电视剧《快乐星球》。上述电影充满科技和…

函数——递归6(c++)

角谷猜想 题目描述 日本一位中学生发现一个奇妙的 定理,请角谷教授证明,而教授 无能为力,于是产生了角谷猜想。 猜想的内容:任给一个自然数, 若为偶数则除以2,若为奇数则乘 3加1,得到一个新的…