【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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HCIP-Datacom-ARST自选题库_10_多种协议多选【24道题】

1.如图所示,PE1和PE2之间通过LoopbackO接口建立MP-BGP邻居关系,在配完成之后,发现CE1和CE2之间无法互相学习路由,下列哪些选项会造成该问题的出现? PE1或PE2未在BGP-VPNV4单播地址族视图使能邻居A PE1或PE2上的VPN实例参数配置错…

windows系统 flutter 开发环境配置

1、管理员运行powershell,安装:Chocolatey 工具,粘贴复制运行下列脚本: Chocolatey 官方安装文档 Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol [System.Net.ServicePointManage…

CSS函数:scale、scale3d函数的使用

CSS函数scale()主要是为了实现元素的放大和缩小效果,使用的是元素的变换效果。使用的是元素的转换属性:transform的,该函数可以实现指定X轴和Y轴的放大、缩小效果。除此之外,我们还可以通过如下两种方式实现指定方向的转换&#x…

【Java】国密SM3/SM4(附工具类)

目录 前言国密算法SM1对称加密算法SM1算法的基本原理SM1算法的应用场景SM1算法的优势代码示例 SM2非对称加密算法SM2算法的基本原理SM2算法的应用场景SM2算法的优势代码示例依赖代码 SM3杂凑算法SM4分组密码算法 SM3、SM4工具类示例依赖SM3工具类SM4工具类CBCECB 前言 目前形式…

[论文笔记]Mixtral of Experts

引言 今天带来大名鼎鼎的Mixtral of Experts的论文笔记,即Mixtral-8x7B。 作者提出了Mixtral 8x7B,一种稀疏专家混合(Sparse Mixture of Experts,SMoE)语言模型。Mixtral与Mistral 7B具有相同的架构,不同之处在于每个层由8个前馈…

SpringCache 缓存 - @Cacheable、@CacheEvict、@CachePut、@Caching、CacheConfig 以及优劣分析

目录 SpringCache 缓存 环境配置 1)依赖如下 2)配置文件 3)设置缓存的 value 序列化为 JSON 格式 4)EnableCaching 实战开发 Cacheable CacheEvict CachePut Caching CacheConfig SpringCache 的优势和劣势 读操作…

Flask 实现增改及分页查询的完整 Demo

Flask 实现增改及分页查询的完整 Demo 简介 本文将通过一个 Flask Demo 来展示如何使用 Flask 框架实现 RESTful API,包括增加、修改用户信息以及分页查询功能。我们将使用 Flask 的扩展 SQLAlchemy 来处理数据库操作。 环境准备 首先,确保你已安装 …

【Android面试题】请你分别采用递归和非递归对二叉树进行遍历?

请你分别采用递归和非递归对二叉树进行遍历? 这道题想考察什么? 1、二叉树的基本原理和遍历的方法? 考察的知识点 二叉树遍历的基本概念、二叉树的基本原理 考生如何回答 二叉树的基本概念 当然可以! 二叉树是一种常见的数据结构,它由一组称为节点的元素构成。每个…

地平线x3派开启core文件存储奔溃日志

开发环境 ubuntu22 ros humble c11 程序奔溃后core文件存储设置 1. 确保系统允许生成core文件 首先,检查和设置系统的core文件生成限制: 检查当前core文件大小限制 使用以下命令检查当前core文件大小限制: ulimit -c如果输出为 0&am…

reduce过滤递归符合条件的数据

图片展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head><…

Python 实现乘数加密法

乘数加密是简单代替密码的一种。乘数加密法脱胎于凯撒加密法,加密和解密符号设计把他们转换成数字,加上或者减去密钥,然后把新的数字转换回符号,当我们把加减密钥变成乘以密钥,就是乘法加密法。有关凯撒加密法可以看之前的文章《Python实现凯撒加解密》。 加密过程 乘数加…

力扣hot100:25. K 个一组翻转链表

LeetCode&#xff1a;25. K 个一组翻转链表 这个题很像24. 两两交换链表中的节点 和 206. 反转链表 的合并体。 在力扣hot100&#xff1a;24. 两两交换链表中的节点中我们使用递归来实现这个问题是很方便的&#xff0c;使用迭代在k个结点一组时就不太好使了&#xff0c;我们可…

【攻击绕过】IP速率限制绕过

【攻击绕过】IP速率限制绕过 1.探测对应功能的API接口2.在代码或参数中插入空白字符3.通过标头操纵IP来源4.修改其他标头5.利用代理网络6.利用 API 网关行为 1.探测对应功能的API接口 应尝试对目标功能的API接口执行暴力攻击&#xff0c;例如/api/v3/sign-up&#xff0c;包括/…

鸿蒙轻内核M核源码分析系列六 任务及任务调度(3)任务调度模块

调度&#xff0c;Schedule也称为Dispatch&#xff0c;是操作系统的一个重要模块&#xff0c;它负责选择系统要处理的下一个任务。调度模块需要协调处于就绪状态的任务对资源的竞争&#xff0c;按优先级策略从就绪队列中获取高优先级的任务&#xff0c;给予资源使用权。本文我们…

nc翻译公式注意事项

nc翻译公式注意事项 翻译3个及以上条件&#xff08;里面加引号的是表名和表中字段&#xff0c;没加引号的是VO中的字段&#xff0c;没加引号的不能是getcolvalue后的字段&#xff09; "pzh->getColValueMore(\"voucherref_view\",\"pk_voucher\"…

关于map并发读写问题的解决方案考虑小计

叠甲&#xff1a;未详细看底层实现&#xff0c;只是大概看了一下涉及的api的源码&#xff0c;理解错的地方勿喷 问题背景 公司业务中用到了一个map&#xff0c;作用是存储需要屏蔽的数据&#xff0c;请求打过来后会去其中匹配 若命中则直接退出 该map的使用有以下几个特点&am…

ffmpeg视频编码原理和实战-(4)H264原始码流分析

H.264是一种广泛使用的视频编码标准&#xff0c;它采用一种分层结构&#xff0c;其中最重要的一个层是NAL&#xff08;网络抽象层&#xff09;。在H.264编码中&#xff0c;原始码流&#xff08;bitstream&#xff09;是由多个NALU&#xff08;NAL Units&#xff09;组成的。了解…

欧洲历史的五个阶段

欧洲的历史基本上都是分裂的&#xff0c;大致可以分为五个时期&#xff0c;分别为古希腊时代、罗马帝国时代、中世纪时代&#xff0c;文艺复兴时代、工业革命时代。 一&#xff0c;古希腊时代 古希腊是西方文明的源头&#xff0c;也是最重要和最直接的文明起源&#xff0c;首…

Python编程学习第一篇——Python零基础快速入门(五)—字典

上期我们学习了List结构&#xff0c;今天大家一起来学习字典。Python中的字典是一种无序的数据类型&#xff0c;用于存储键值对(key-value)。它是一种可变的数据结构&#xff0c;可以在其中添加、删除和修改元素。字典中的键必须是唯一的&#xff0c;而值可以重复。 下面我们以…