【Git】Git 的基本操作 -- 详解

一、创建 Git 本地仓库

要提前说的是,仓库是进行版本控制的一个文件目录。我们要想对文件进行版本控制,就必须先创建一个仓库出来。

创建⼀个 Git 本地仓库对应的命令为 git init ,注意命令要在文件目录下执行,例如:

我们发现,当前目录下多了一个 .git 的隐藏文件,.git 目录是 Git 来跟踪管理仓库的,不要手动修改这个目录里面的文件,不然改乱了,就把 Git 仓库给破坏了。

其中包含 Git 仓库的诸多细节:


二、配置 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 仓库都会使用这个配置。如果希望在不同仓库中使用不同的 name e-mail,可以不要 --global 选项,但要注意的是,执行命令时必须要在仓库里。


1、查看配置命令

git config -l


2、删除对应的配置命令

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

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

1、工作区

在电脑上你要写代码或文件的目录。


2、暂存区(stage 或 index)

⼀般存放在 .git 目录下的 index 文件(.git/index)中,我们把暂存区有时也叫作索引(index)。


3、版本库(Repository)

又名仓库 。工作区有一个隐藏目录 .git ,它不算工作区,而是 Git 的版本库。这个版本库里面的所有文件都可以被 Git 管理起来,每个文件的修改、删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以 “还原”。


下面这个图展示了工作区、暂存区和版本库之间的关系:

  • 图中左侧为工作区右侧为版本库。Git 的版本库里存了很多东西,其中最重要的就是暂存区

  • 在创建 Git 版本库时,Git 会为我们自动创建一个唯一的 master 分支,以及指向 master 的⼀个指针叫 HEAD

  • 当对工作区修改(或新增、删除)的文件执行 git add 命令时,暂存区目录树的文件索引会被更新。

  • 当执行提交操作 git commit 时,master 分支会做相应的更新,可以简单理解为暂存区的目录树才会被真正写到版本库中。

由上述描述我们便能得知:通过新建或粘贴进目录的文件,并不能称之为向仓库中新增文件,而只是在工作区新增了文件。必须要通过使用 git add git commit 命令才能将文件添加到仓库中进行管理。


四、添加文件(一)

在包含 .git 的目录下新建一个 ReadMe ⽂件,但在目前情况下,Git 还不能管理我们的 ReadMe 文件。

可以使用 git add 命令可以将文件添加到暂存区:

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

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

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

  • 再使用 git commit 命令将暂存区内容添加到本地仓库中:

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

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

git commit 命令执行成功后会告诉我们,1 个文件被改动(就是我们新添加的 ReadMe 文件),插入了一行内容(ReadMe 有一行内容)。 还可以多次 add 不同的文件,而只 commit 一次便可以提交所有文件,是因为需要提交的⽂件是通通被 add 到暂存区中,然后一次性 commit 暂存区的所有修改。如:

注意git commit 后面-m 选项,要跟上描述本次提交的 message,由用户自己完成,这部分内容绝对不能省略,并要好好描述,是用来记录你的提交细节,是给我们自己看的。

截至目前为止,我们已经更够将代码直接提交至本地仓库了。可以使用 git log 命令,来查看下历史提交记录:

该命令显示从最近到最远的提交日志,并且可以看到我们 commit 时的日志消息。如果担心输出的信息太多,看得眼花缭乱,可以试试加上 --pretty=oneline 参数:

需要说明的是,我们看到的一大串类似 c64e0871...9c6502 的是每次提交的 commit id(版本号),Git 的 commit id 不是 1,2,3…… 递增的数字,而是⼀个 SHA1 计算出来的一个非常大的数字,用十六进制表示。


五、查看 .git 文件

先来看看我们的 .git 的目录结构:

  • index 就是我们的暂存区,add 后的内容都是添加到这里的

  • HEAD 就是我们的默认指向 master 分支的指针

上面就是我们默认的 master 分支。

打印的 c64e0871d6aaf40315d85200eb32c558bd9c6502 是什么东西呢?

保存的就是当前最新的 commit id

  • objects Git 的对象库,里面包含了创建的各种版本库对象及内容。当执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,就位于 ".git/objects" 目录下,来看看这些对象有何用处:

查找 object 时要将 commit id 分成 2 部分,其前 2 位是文件夹名称,后 38 位是文件名称。找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过 sha (安全哈希算法)加密过的文件,好在我们可以使用 git cat-file 命令来查看版本库对象的内容:

这就是我们最近⼀次的提交。

其中,还有一行 tree 15a37e9ef171cca4a5d985fccd1fcf9414b2c7cf,我们使用同样的方法,看看结果:

再看 ReadMe 对应的 8d0e41234f24b6da002d962a26c2495ea16a425f:

这是我们对 ReadMe 做的修改,被 git 记录了下来。

总结一下,在本地的 git 仓库中,有几个文件或者目录很特殊

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

后面再在学习的过程中,最好能将常见的 git 操作与 .git 目录当中的结构内容变化对应起来,这样有利于理解 git 细节流程。


六、添加文件(二)

下面展示另一种添加文件的场景,能加深对工作区、暂存区、版本库的理解,示例如下:

  1. 新增 file4 文件
  2. 将 file4 添加到暂存区
  3. 新增 file5 文件
  4. 提交修改

提交后发现打印了 1 file changed, 0 insertions(+), 0 deletions(-) ,意思是只有一个文件改变了,难顶不是新增了两个文件吗?

git add 是将文件添加到暂存区,git commit 是将暂存区的内容添加到本地仓库中。由于我们并没有使用 git add file5 ,file5 就不在暂存区中维护,所以在 commit 的时候其实只是把已经在暂存区的 file4 提交了,而遗漏了工作区的 file5。

如何提交 file5 呢?

再次 add,commit 即可。


七、修改文件

Git 比其他版本控制系统设计得优秀,因为 Git 跟踪并管理的是修改,而非文件。


1、什么是修改

比如你新增了一行,这就是一个修改,删除了一行,也是⼀个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。

让我们将 ReadMe 文件进行一次修改:

此时,仓库中的 ReadMe 和我们工作区的 ReadMe 是不同的。

如何查看当前仓库的状态呢?

用命令:git status 来查看在你上次提交之后是否有对文件进行再次修改。

上面的结果告诉我们,ReadMe 被修改过了,但还没有完成添加与提交。目前,我们只知道文件被修改了,如果能知道具体哪些地方被修改了,就更好了。可是我们还会记得一周之前写了什么代码吗,或者没写。

命令:git diff [file] 用来显示暂存区和工作区文件的差异,显示的格式正是 Unix 通用的 diff 格式。也可以使用 git diff HEAD -- [file] 命令来查看版本库和工作区文件的区别。知道了对 ReadMe 做了什么修改后,再把它提交到本地仓库就放心多了。

git add 之后,就没有看到上面 no changes added to commit (use "git add" and/or "git commit -a") 的消息了,接下来继续 git commit 即可:


八、版本回退

前面也讲到过,Git 能够管理文件的历史版本,这也是版本控制器重要的能力。如果有一天发现之前的工作出现了很大的问题,需要在某个特定的历史版本重新开始,那么这个时候就需要用到版本回退的功能了。

执行 git reset 命令用于回退版本,可以指定退回某⼀次提交的版本。要解释一下 “回退” 的本质是要将版本库中的内容进行回退,工作区或暂存区是否回退由命令参数决定:

git reset 命令语法格式为: git reset [--soft | --mixed | --hard] [HEAD]

  • --mixed 为默认选项,使用时可以不用带该参数。该参数将暂存区的内容退回为指定提交版本内容,工作区文件保持不变。

  • --soft 参数对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。

  • --hard 参数将暂存区与工作区都退回到指定版本。切记工作区有未提交的代码时不要用这个命令,因为工作区会回滚,你没有提交的代码就再也找不回了,所以使用该参数前一定要慎重。

  • HEAD 说明:

  1. 可直接写成 commit id,表示指定退回的版本。

  2. HEAD 表示当前版本。

  3. HEAD^ 表示上一个版本。

  4. HEAD^^ 表示上上一个版本。

  5. 以此类推...

  • 可以使用 ~ 数字表示:

  1. HEAD~0 表示当前版本。

  2. HEAD~1 表示上一个版本。

  3. HEAD^2 表示上上一个版本。

  4. 以此类推...

为了便于表述,方便测试回退功能,先做一些准备工作:更新 3 个版本的 ReadMe,并分别进行 3 次提交,如下所示:

如果我后悔了上面的操作,想再回去怎么办?

可以继续使用 git reset 命令,回退到原先的版本,但我们必须要拿到原先版本commit id 去指定回退的版本。

但我们看到了 git log 并不能打印出之前版本commit id ,运气好的话我们可以从终端上去找找之前的历史记录,运气不好的话 commit id 已经被我们搞丢了。不过 Git 还提供了⼀个 git reflog 命令能够补救一下,这个命令用来记录本地的每一次命令。

这样就可以很方便的找到我们的所有操作记录了,但这个 c752678 这个是什么?

是原先最新的版本。Git 版本回退的时候,也可以使用部分 commit id 来代表目标版本

可以发现,此时 ReadMe 文件的内容,已经回退到最开始提交的时候了。

但在实际开发中,由于长时间的开发,导致 commit id 早就找不到了,可是突然又想回退到之前的版本,那该如何操作呢?

貌似现在就不可能做到了,但值得说的是,Git 的版本回退速度非常快,因为 Git 在内部有个指向当前分支(此处是 master)的 HEAD 指针, refs/heads/master 文件里保存当前 master 分支的最新 commit id 。当我们在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储⼀个特定的 version,可以简单理解成如下示意图:


九、撤销修改

如果我们在我们的工作区写了很长时间代码,越写越写不下去,想恢复到上⼀个版本。


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

新增代码后:

可以直接删掉目前在工作区新增的代码,但如果我们写了 3 天,⼀直都没有提交,该怎么删掉呢?自己忘了新增过哪些,可以 git diff xxx ⼀下,看看差别再删。

那我们肯定又要花上 3 天时间来删代码了,并且很大的概率还会改出 bug。Git 其实还为我们提供了更好的方式,可以使用 git checkout -- [file] 命令让工作区的文件回到最近一次 add commit 时的状态

注意 git checkout -- [file] 命令中的 -- 很重要,切记不要省略。⼀旦省略,该命令就变为其他意思了。


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

回忆⼀下上面讲的 git reset 回退命令,该命令如果使用 --mixed 参数,可以将暂存区的内容退回为指定的版本内容,但工作区文件保持不变,那我们就可以回退下暂存区的内容了。

用 git status 查看⼀下,发现现在暂存区是干净的,工作区有修改。

注意--mixed 是默认参数,使用时可以省略。

如何丢弃工作区的修改呢?


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

可以 git reset --hard HEAD^ 回退到上⼀个版本。但是这么做有条件的,就是还没有把自己的本地版本库推送到远程。⼀旦推送到远程版本库,就撤回不了了。



十、删除文件

在 Git 中,删除也是⼀个修改操作

如果要删除 file5 文件,要怎么操作呢?如果是按照下面这种做法:

这样直接删除是没有用的,反而徒增烦恼, git status 命令会立刻告诉我们哪些文件被删除了:

此时,工作区和版本库就不⼀致了,要删文件,目前除了要删工作区的文件,还要清除版本库的文件。

⼀般走到这里,有两种可能

  • 确实要从版本库中删除该文件。
  • 不小心删错了。

对第二种情况,很明显误删,需要使用 git 来进行恢复,很简单,我们刚学过(删除也是修改):

对于第一种情况,很明显是没有删完,我们只删除了工作区的文件。这时就需要使用 git rm 将文件从暂存区和工作区中删除,并且 commit

现在,文件就从版本库中被删除了。

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

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

相关文章

力扣hot100:155. 最小栈(栈,辅助栈存储相关信息)

LeetCode:155. 最小栈 1、尝试单调栈 看到这题说,要常数时间内检索最小元素的栈,想到了单调栈,递增单调栈确实能维护最小值,但是这个最小值是存在一定意义的,即如果后面出现了最小值,那么前面…

MineAdmin 前端打包后,访问速度慢原因及优化

前言:打包mineadmin-vue前端后,访问速度很慢,打开控制台,发现有一个index-xxx.js文件达7M,加载时间太长; 优化: 一:使用文件压缩(gzip压缩) 1、安装compre…

Elastic Search (ES)Java 入门实操(1)下载安装、概念

实现数据查询代码:Elastic Search(ES)Java 入门实操(2)搜索代码-CSDN博客 Elastic Search(ES)Java 入门实操(3)数据同步-CSDN博客 Elastic Search 官方描述&#xff0c…

Web前端指南

前言 前端开发员主要负责网站的设计、外观和感觉。他们设计引人入胜的在线用户体验,激发用户兴趣,鼓励用户重复访问。他们与设计师密切合作,使网站美观、实用、快捷。 如果您喜欢创造性思维、打造更好的体验并对视觉设计感兴趣,这将是您的理想职业道路。 探讨前端、后端以…

python数据分析-心脏衰竭分析与预测

研究背景 人的心脏有四个瓣膜,主动脉银、二尖、肺动脉和三尖源 不管是那一个膜发生了病变,都会导致心脏内的血流受到影响,这就是通常所说的心脏期膜病,很多是需要通过手术的方式进行改善的。随着人口老龄化的加剧,,心…

Centos7 安装配置SFTP

Centos7安装配置SFTP 更新源安装 OpenSSH 服务启动服务设置为开机自启动新建一个用户 (sftpuser为你要设置的用户的用户名)编辑配置文件设置sftp用户的根目录重启SSH服务代码实现 由于最近工作中需要实现动态上传文件到帆软服务器,但是帆软没有提供相关API&#xff…

SAP 服务提供者 (Services Provider)接口测试笔记

文章目录 SAP 服务提供者 (Services Provider)接口测试笔记设置Content-Type授权SAP接口测试-SoapUI参数配置 SAP 服务提供者 (Services Provider)接口测试笔记 现在我在SAP里面公布了一些查询接口,现在就是要用SoapU…

JVM面试基本问题整理

文章目录 1、说下对JVM内存模型的理解2、运行时常量池的位置3、常量池和运行时常量池的区别4、内存溢出和内存泄漏5、Java 对象大小计算6、GCROOT都有什么7、常用的JVM启动参数有哪些8、TLAB 1、说下对JVM内存模型的理解 1)线程私有区域 程序计数器(Pro…

转让无区域商业管理公司挺批行业包变更

无区域的名称我们可以直接进行名称的申请核准。 从新规施行之后,国家局核名批准难度更高。新申请的无区域名称已经停批了,进行核名将更难,而需要满足一定条件并在成立一年后才能变更升级名称。而这个过程并非易事,难度非常高。可以…

微信小程序 画布canvas

属性说明 属性类型默认值必填说明最低版本typestring否指定 canvas 类型,支持 2d (2.9.0) 和 webgl (2.7.0)2.7.0canvas-idstring否canvas 组件的唯一标识符,若指定了 type 则无需再指定该属性1.0.0disable-scrollbooleanfalse否当在 canvas 中移动时且…

第二十讲:文件操作

第二十讲:文件操作 1.什么是文件1.1什么是文件1.1.1程序文件1.1.2数据文件 1.2二进制文件和文本文件数据的存储方式 2.流和标准流2.1流2.2标准流 3.文件指针4.文件的打开与关闭5.文件顺序读写5.1顺序读写函数介绍5.2打开和关闭函数5.2.1fopen函数5.2.2fclose函数 5.…

U盘文件系统结构损坏的应对与预防

在数字化时代,U盘作为便携式存储设备,其重要性不言而喻。然而,当U盘文件系统结构损坏时,我们可能会面临数据丢失的风险。本文将深入探讨U盘文件系统结构损坏的问题,分析其产生的原因,并给出相应的数据恢复方…

零基础入门学用Arduino 第一部分(三)

重要的内容写在前面: 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后,整体感觉是很好的,如果有条件的可以先学习一些相关课程,学起来会更加轻松,相关课程有数字电路…

深度学习:如何静悄悄地改变我们的日常生活

深度学习 深度学习:如何静悄悄地改变我们的日常生活一、消费电子产品智能手机与个人助理娱乐与社交媒体 二、医疗健康三、汽车与交通四、公共安全五、总结 深度学习:如何静悄悄地改变我们的日常生活 在近年来,深度学习技术因其强大的数据处理…

GO语言 服务发现概述

https://zhuanlan.zhihu.com/p/32027014 明明白白的聊一下什么是服务发现-CSDN博客 一、服务发现 是什么 在传统的系统部署中,服务运行在一个固定的已知的 IP 和端口上,如果一个服务需要调用另外一个服务,可以通过地址直接调用。 但是&…

linux本地搭建dns

不需要图形化界面 使用的是dnsmasq,配置简单 1.安装 deb系列linux apt-get install dnsmasqrhat系列linux yum install dnsmasq2.编辑配置文件 vi /etc/dnsmasq.conf设置主dns服务器,比如现有公用的的114.114.114.114 8.8.8.8这类的 server8.8.8.8…

IEDA集成依赖概述

IEDA集成依赖概述 目录概述需求: 设计思路实现思路分析1.NoSQL Spring Data Redis (AccessDriver)Spring Data Reactive RedisSpring Data MongoDBSpring Data Reactive MongoDBSpring Data for Apache CassandraSpring Data Reactive for Apache CassandraSpring D…

传统工科硕士想转嵌入式,时间够吗?

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!! 零基础开始学&#xff0…

ArcGIS for js 4.x 加载图层

二维&#xff1a; 1、创建vue项目 npm create vitelatest 2、安装ArcGIS JS API依赖包 npm install arcgis/core 3、引入ArcGIS API for JavaScript模块 <script setup> import "arcgis/core/assets/esri/themes/light/main.css"; import Map from arcgis…

本地运行feishu-chatgpt项目结合内网穿透实现无公网IP远程访问

文章目录 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 前言 本文主要介绍如何在飞书中创建chatGPT机器人并且结合内网穿透工具…