【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…

[论文笔记]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 的优势和劣势 读操作…

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;我们可…

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

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

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

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

欧洲历史的五个阶段

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

nexus搭建npm前端项目的私服

一、为什么要搭建私库 节省外网带宽加速maven构建部署第三方构件&#xff08;特别是无法从公共仓库下载的构件&#xff09;提高稳定性&#xff08;内网部署&#xff0c;更少地依赖外网&#xff09;降低中央仓库的负荷 构件&#xff0c;好比我们的藏书&#xff0c;去书店或商城…

深度学习——TensorBoard的使用

官方文档torch.utils.tensorboard — PyTorch 2.3 documentation TensorBoard简介 TensorBoard是一个可视化工具&#xff0c;它可以用来展示网络图、张量的指标变化、张量的分布情况等。特别是在训练网络的时候&#xff0c;我们可以设置不同的参数&#xff08;比如&#xff1…

【kubernetes】探索k8s集群的pod控制器详解(Deployment、StatefulSet、DaemonSet、Job、CronJob)

目录 一、Pod控制器及其功用 二、pod控制器有多种类型 2.1ReplicaSet 2.1.1ReplicaSet主要三个组件组成 2.2Deployment 2.3DaemonSet 2.4StatefulSet 2.5Job 2.6Cronjob 三、Pod与控制器之间的关系 3.1Deployment 3.2SatefulSet 3.2.1StatefulSet三个组件 3.2.2为…

力扣 54.螺旋矩阵

题目描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#…

什么是Spark RDD?(RDD的介绍与创建)

什么是Spark RDD&#xff1f;(RDD的介绍与创建) 一、RDD介绍 1、特点2、RDD的存储和指向3、RDD与DAG4、RDD的特性5、RDD分区6、RDD操作类型 二、RDD创建 1、引入必要的 Spark 库2、配置 Spark3、RDD创建4、示例代码 一、RDD介绍 RDD: 弹性分布式数据集&#xff08;Resilient…

【PCB]射频电路pcb设计

学习改变命运&#xff0c;技能成就未来&#xff01;❤~~ 1射频信号的基础知识及工作原理介绍 射频的基础知识介绍 2射频板PCB的布局要求 3射频板布局要求 4屏蔽帐设计 5射频板的层叠阻抗设计 6射频板的PCB布线原则 7射频板的PCB布线要求 8射频板的设计实战

10个令人惊叹的Python自动化脚本

大家好&#xff0c;Python凭借其简单和通用性&#xff0c;能够为解决每天重复同样的工作提供最佳方案。本文将介绍10个Python自动化脚本&#xff0c;可以帮助自动化完成任务&#xff0c;提高工作效率&#xff0c;它们可以成为项目运行中的便捷工具&#xff0c;可以收藏这些脚本…

AI办公自动化:用kimi批量提取音频中的标题并重命名

很多音频文件&#xff0c;文件名很乱&#xff0c;需要根据音频信息中的标题聪明吗 在kimi中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;一步步的思考&#xff0c;完成以下脚本的撰写&#xff1a; 打开文件夹&#xff1a;E:\有声\a16z播客 读取里面所有的mp3格…

ARM的工作模式

ARM的几种工作模式 User : 非特权模式&#xff0c;大部分任务执行在这种模式 FIQ : 当一个高优先级&#xff08;fast) 中断产生时将会进入这种模式IRQ : 当一个低优先级&#xff08;normal) 中断产生时将会进入这种模式 Supervisor&#xff08;SVC&#xff09; : 当复位或软中断…