Git 工作区、暂存区与修改全解析

news2024/9/27 12:06:18

工作区和暂存区是 Git 中一个非常重要的概念,弄明白了他们,就弄明白了 Git 的很多操作到底干了什么。

工作区(Working Directory)

工作区,就是一个目录,比如我的 LearnGit ​文件夹就是一个工作区:

我们平时更新版本什么的,都是在这里完成的,可以理解成是在这里工作的。

版本库(Repository)

工作区有一个隐藏目录 .git​,这个不算工作区,而是 Git 的版本库。

Git 的版本库里存了很多东西,其中最重要的就是称为 stage​​(或者叫 index)的暂存区,还有 Git 为我们自动创建的第一个分支 master​​,以及指向 master​​的一个指针叫 HEAD​​。(分支的概念我们后续介绍)

前面讲了我们把文件往 Git 版本库里添加的时候,是分两步执行的:

  • 第一步是用 git add​ 把文件添加进去,实际上就是把文件修改添加到暂存区。
  • 第二步是用 git commit​​提交更改,实际上就是把暂存区的所有内容提交到当前分支,这里是 master 分支。在我们创建 Git 版本库时,Git 会自动为我们创建 master​​分支。

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

在.git 文件夹里面有一个 index 文件,就是暂存区。

通过 「git status」 查看 「git」 状态时, 「红色」 的文件表示在 「工作区」「绿色」 的文件表示在 「暂存区」。

实践是检验标准的唯一真理

我们来逐步说明下,一个文件是怎么提交的。首先我们吸怪下 readme.txt,加上一行:

$ echo "Git has a mutable index called stage." >> readme.txt

$ cat .\readme.txt
Git is a distributed version control system
Git is free software distributed under the GPL.
Git has a mutable index called stage.

并且,新添加一个文件,叫做 LICENSE:

$ echo "something" > LICENSE
$ cat LICENSE
something

然后我们查看下仓库状态:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   readme.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        LICENSE

Git 非常清楚地告诉我们,readme.txt ​被修改了,而 LICENSE ​还从来没有被添加过,所以它的状态是 Untracked​。

现在,使用两次命令 git add​,把 readme.txt ​和 LICENSE ​都添加后,用 git status ​再查看一下:

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   LICENSE
        modified:   readme.txt

现在,暂存区的状态就变成这样了:

git-stage

所以,git add ​命令实际上就是把要提交的所有修改放到暂存区(Stage)。

接下来,我们提交:

$ git commit -m "understand how stage works"
[master 8f5bb58] understand how stage works
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 2-versionControl/LICENSE

此时,工作区就是干净的了:

$ git status
On branch master
nothing to commit, working tree clean

现在版本库变成了这样,暂存区就没有任何内容了:

git-stage-after-commit

管理修改

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

举个例子,假设目前 readme.txt 有 114514 行,然后你在最后一行添加了一句话;

在使用版本控制工具之前,我们的备份方式可能就是直接复制一份 readme.txt,然后再后面再追加一行。此时我们就有了两个文件:

readme.txt        //新版本的
readme.txt.backup //旧版本的

并且,这两个文件是相差无几的!很多内容都是一样的(除了最后一行),这会造成存储空间的浪费。

而 Git,管理的是修改。比如,你增加了一行内容后,Git 会记录这个修改:增加了一行,内容为“xxxx”,这样,如果想要回退到上一个版本,只需将上次修改的内容撤销就可以了!相比重复存储一个文件的方式,大大节省了存储空间的浪费,还可以直接查看修改,而不是将前后两个版本的文件用 diff 比较后才能得到差异。

在 Git 中,添加一个文件,修改文件里的内容,删除一个文件,都算一个修改。

暂存区里的修改

在 Git 中,我们每次修改得先放到暂存区,只有暂存区里的修改才会被 commit,我们修改下 readme.txt:

$ echo "Git tracks changes." >> readme.txt

$ cat readme.txt
Git is a distributed version control system
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes.

此时我们查看下仓库状态,可以看到已经添加到暂存区了,可以被提交了:

$  git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   readme.txt

我们再次修改 readme.txt:

$ cat readme.txt 
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.

然后提交:

$ git commit -m "git tracks changes"
[master aeb06f4] git tracks changes
 1 file changed, 0 insertions(+), 0 deletions(-)

然后再次查看仓库状态:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   readme.txt

可以看到第二次的修改,并没有被提交!只有 git add ​后,才会把修改提交到暂存区,git commit ​只负责把暂存区的修改提交了。

撤销修改

当你在工作区里写代码的时候,突然发现写错文件了,这些代码应该是写到另一个文件的,怎么办呢?

你可以打开文件,然后手工删除自己加上去的代码,但这样不仅费时费力,还可能删错或者删漏代码。

其实,在修改文件后,如果查看仓库状态,Git 会很贴心的告诉你怎么丢弃工作区的修改。我们来测试下:

$ echo "AAA" >> readme.txt   //假设这是错误的代码
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
AAA

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

Git 告诉我们,使用 “git restore <file>​…” 可以丢弃(discard )工作区里的修改,我们来测试下:

$ git restore readme.txt
$ cat readme.txt
Git is a distributed version control system
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes.

可以看到我们的修改确实被丢弃了,如果想要撤销工作区的所有修改:git resotre .

撤销工作区的所有修改

如果你不仅在工作区里修改了,还添加到了暂存区怎么办?同样的,我们查看仓库状态的时候,Git 也会贴心的告诉我们怎么丢弃暂存区里的修改:

$ echo "AAA" >> readme.txt
$ cat readme.txt
Git is a distributed version control system
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes.
AAA


$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   readme.txt

Git 告诉我们,使用 “git restore --staged <file>...​” 可以丢弃暂存区里的修改(unstage)。我们来试试:

$ git restore --staged readme.txt

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

可以看到目前暂存区里是空的,没有需要提交的,如果要提交着用 git add​。

还有其他类似的命令可以撤销修改,例如在廖雪峰老师的博客里撤销修改 ,这样写到:

场景 1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令 git checkout -- file

场景 2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令 git reset HEAD <file>​,就回到了场景 1,第二步按场景 1 操作。

Git 是一直在更新的,有些新版本提供了新的命令,个人认为 restore 更加好记一点。

删除文件

在 Git 中,删除也是一个修改操作,我们实战一下,先添加一个新文件 test.txt ​到 Git 并且提交:

$ git add test.txt

$ git commit -m "add test.txt"
[master 8889d50] add test.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

一般情况下,我们可以在文件管理器中把没用的文件删了,或者用 rm ​命令删了:

$ rm test.txt

目前工作区和版本库的版本就不一致了,使用 git status ​可以看到哪些文件被删除了:

$ git status
On branch master
Your branch is ahead of 'gitee/master' by 3 commits.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    test.txt
no changes added to commit (use "git add" and/or "git commit -a")

我们可以使用提交这次修改:

$ git add test.txt

$ git commit -m "delete test.txt"
[master b391595] delete test.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 test.txt

使用 git rm​​:一步到位

注意我们刚刚是先删除,然后再 add 和 commit 的,我们可以简化为一条命令:git rm​。

首先我们准备下文件

$ echo "test" > test.txt
$ git add test.txt
$ git commit -m "add test.txt"
[master 42c477d] add test.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

然后使用 git rm​,并查看仓库状态

$ git rm test.txt
rm 'test.txt'

$ git st
On branch master
Your branch is ahead of 'gitee/master' by 5 commits.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    test.txt

可以看到文件被删除了,并且本次删除已经被提交到了暂存区,可以 commit 了,我们再次提交,结束。

$ git commit -m "delete test.txt"

以下两种情况,不能正常使用 git rm

  • 工作区是 clean 的,然后修改了工作区的文件;
  • 工作区是 clean 的,然后修改了工作区的文件,并提交到暂存区

我们可以加上-f 参数,git rm -f​,表明强制删除。

git rm -f​​​

先准备文件:

$ echo "test" > test.txt
$ git add test.txt
$ git commit -m "add test.txt"

修改文件后使用 git rm​:会提示不能删除

$ echo "test" >> test.txt

$ git rm test.txt
error: the following file has local modifications:
    test.txt
(use --cached to keep the file, or -f to force removal)

我们可以使用 git rm -f ​文件名来强制删除

$ git rm -f test.txt
rm 'test.txt'

$ git st
On branch master
Your branch is ahead of 'gitee/master' by 7 commits.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    test.txt

如果我们误删了怎么办呢?还是和之前一样,使用 git restore --staged <file> ​来将修改从暂存区里拿出来,然后再使用 git restore <file> ​来恢复数据:

$ git restore --staged test.txt
$ git restore test.txt
$ ll
total 7
drwxr-xr-x 1 peterjxl 197121  0  111 07:37 1-diffAndPath/
drwxr-xr-x 1 peterjxl 197121  0  114 07:19 2-versionControl/
-rw-r--r-- 1 peterjxl 197121  6  114 11:58 test.txt

注意:

  • 从来没有被添加到版本库就被删除的文件,是无法恢复的!
  • 如果想删除文件夹,使用-r 参数,例如 git rm -r 文件夹

git rm --cached

使用 git rm --cached,可以使一个文件脱离版本控制 演示:

首选准备数据

$ echo "test" > test.txt
$ git add test.txt
$ git commit -m "add test.txt"

然后使用 git rm --cached test.txt

$ git rm --cached test.txt
rm 'test.txt'

查看仓库状态,可以看到删除文件这个修改已经添加到暂存区了,并且 test.txt 目前是 Untracked

$ git st
On branch master
Your branch is ahead of 'gitee/master' by 7 commits.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    test.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        test.txt

但是工作区里的文件还在:

$ ll
drwxr-xr-x 1 peterjxl 197121  0  111 07:37 1-diffAndPath/
drwxr-xr-x 1 peterjxl 197121  0  114 07:19 2-versionControl/
-rw-r--r-- 1 peterjxl 197121  6  114 11:58 test.txt

我们提交下,结束演示

$ git commit -m "delete test.txt by git rm --chched"

小结

小结:本文我们主要介绍了如下内容:

  • 版本库,工作区和暂存区的概念,这对理解 Git 非常重要。
  • Git 是管理修改的,添加文件、修改文件内容和删除文件都是一种修改
  • 撤销修改 git restore <file>...​, git restore --staged <file>...

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

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

相关文章

JavaScript --模版字符串用反引号

用反引号 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, i…

SpringBoot集成阿里easyexcel(一)基础导入导出

easyexcel主要用于excel文件的读写&#xff0c;可使用model实体类来定义文件读写的模板&#xff0c;对开发人员来说实现简单Excel文件的读写很便捷。可参考官方文档 https://github.com/alibaba/easyexcel 一、引入依赖 <!-- 阿里开源EXCEL --><dependency><gr…

《深度学习》ResNet残差网络、BN批处理层 结构、原理详解

目录 一、关于ResNet 1、什么是ResNet 2、传统卷积神经网络存在的问题 1&#xff09;梯度消失和梯度爆炸问题 2&#xff09;训练困难 3&#xff09;特征表示能力受限 4&#xff09;模型复杂度和计算负担 3、如何解决 1&#xff09;解决梯度问题 BN层重要步骤&#xff1a; 2…

Gstreamer中,使用mp4或者flv作为视频源去推流RTP等视频流时,需要先解码在编码才能正常

前言&#xff1a; 在Gstreamer中&#xff0c;视频源可以有很多&#xff0c;在很多时候&#xff0c;我们为了测试&#xff0c;会使用MP4等文件作为视频源进行测试&#xff0c;但是发现无论是我自己测试&#xff0c;还是很多网上的命令&#xff0c;都需要先对mp4的h264数据解码以…

等保测评实战:构建企业网络安全的铜墙铁壁

在数字化转型的浪潮下&#xff0c;企业面临的网络安全威胁日益复杂多变。信息安全等级保护&#xff08;等保&#xff09;测评作为国家强制性标准&#xff0c;不仅检验着企业的网络安全防护能力&#xff0c;更是企业构建网络安全“铜墙铁壁”的实战指南。本文将从实战角度&#…

华为云徐峰:AI赋能应用现代化,加速软件生产力跃升

2024年9月19日&#xff0c;在华为全联接大会2024的“AI赋能应用现代化&#xff0c;加速软件生产力跃升”论坛上&#xff0c;华为云PaaS服务产品部部长徐峰发表了主题演讲&#xff0c;介绍了未来应用智能化演进趋势&#xff0c;分享了智能化应用的行业实践&#xff0c;并发布了华…

Elasticsearch 启动后在浏览器输入http://localhost:9200 访问失败

windows Elasticsearch 启动后在浏览器输入http://localhost:9200 访问失败 文章目录 前言本地下载安装了个elasticsearch&#xff0c;启动成功了&#xff0c;在本地访问http://localhost:9200 无法访问&#xff01;&#xff01;&#xff01;难受了一下。 一、windows Elastics…

从文本图片到多模态:3D 数字人打开企业全域商业增长新空间

摘要&#xff1a;数字化与AI浪潮推动各行业变革&#xff0c;内容形式也发生巨变&#xff0c;从文本到多媒体的多模态表达&#xff0c;标志着内容创造走向升维。AIGC 3D生成技术的突飞猛进&#xff0c;彻底打破了传统3D内容生产门槛高、周期长、成本高昂的问题。将3D数字人的打造…

两种调用智谱AI API的方式

一、 用智谱AI依赖包调用 from zhipuai import ZhipuAI zhipuai_api_keyXXXXXXXXXXXXXXXXXX # 请填写您自己的APIKeymessages[{"role": "system", "content": "你是一名经验丰富的人工智能工程师&#xff0c;请你解答用户的问题"},{…

前端文件下载全流程

一、首先是点击下载函数功能 源代码&#xff1a; java const dow async (record: any) > {console.log(record,record);let date: any {}date.pcno record.pcnodate.fileName record.fileNamedate.gmtCreated dayjs(record.gmtCreated).format(YYYY-MM)date.importSta…

Electron 更换窗口图标、exe执行文件图标

首先在项目根目录下准备好图标&#xff1a; 配置窗口图标&#xff1a; 配置打包后 exe执行文件 的图标&#xff1a; 效果展示&#xff1a;

gitlab默认克隆地址的修改

目录 1.找到opt/gitlab/embedded/service/gitlab-rails/config目录&#xff0c;打开gitlab.yml 2.修改地址和端口 3.重启gitlab 1.找到opt/gitlab/embedded/service/gitlab-rails/config目录&#xff0c;打开gitlab.yml cd /opt/gitlab/embedded/service/gitlab-rails/confi…

扩展uview复选组件库支持自定义图片+自定义内容

uView 是一套基于UniApp 的前端 UI 框架&#xff0c;它提供了丰富的组件库&#xff0c;用于快速开发移动端和微信小程序等应用。 基本使用 在 uView 中&#xff0c;复选组件通常用于让用户从一组选项中选择多个项目。这些组件可能以 Checkbox Group&#xff08;复选框组&…

python - 在linux上编译py文件为【.so】文件部署项目运行

python - 在linux上编译py文件为【.so】文件&#xff0c;可通过主文件直接执行 一. 前言 在Python中&#xff0c;通常不直接将Python代码编译为.so&#xff08;共享对象&#xff09;文件来执行&#xff0c;因为.so文件是编译后的二进制代码&#xff0c;通常用于C或C等语言&am…

Centos7.9在K8s安装生产级别的分布式存储Rook+Ceph

1.介绍 在k8s云原生平台中&#xff0c;存储是除了网络之外的另一个核心&#xff0c;因为他涉及到了数据的保存&#xff0c;以及容灾等一系列的问题&#xff0c;做生产级别的应用&#xff0c;一定要具有多节点分布式&#xff0c;灾备及时恢复&#xff0c;数据平滑迁移等多种特性…

WDM站点类型 -- 波分站点类型

OTM OTM: Optical Terminal Multiplerer 光终端复用站 OTM站点将业务信号通过合波单元插入到波分系统的线路上去&#xff0c;同时可将业务经过分波 单元从波分系统的线路上分下来。 OLA OLA: Optical Line Amplifier 光线路放大设备 OLA站点用来完成双向传输信号的放大&#xf…

【Python】Windows下安装使用FFmpeg

FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。之前为了MP3转wav&#xff0c;需要pip安装并import AudioSegment&#xff0c;但是会报错&#xff1a;FileNotFoundError: [WinError 2] 系统找不到指定的文件。 因为FFmpeg需要另…

怎么利用PHP发送彩信

在数字化时代&#xff0c;信息传播的速度与效率成为了企业营销、客户服务及日常沟通中不可或缺的关键因素。随着移动通信技术的飞速发展&#xff0c;群发彩信作为一种集文字、图片、声音于一体的多媒体信息服务方式&#xff0c;正逐渐展现出其独特的优势&#xff0c;成为众多行…

MySQL InnoDB undo log数据结构分析

一、概念解析 1、undo log基本 undo log是InnoDB事务中特有的结构&#xff0c;它的作用有两个&#xff1a;一是进行事务回滚&#xff08;原子性&#xff09;&#xff0c;旧数据先放到undo log中&#xff0c;等rollback时再将旧数据里的数据回滚回来&#xff1b;二是MVCC&…

UE5 Windows热更新解决方案思路(HotPatcher+Tomcat+RuntimeFilesDownloader)

以下个人学习笔记。其中必会存在一些问题&#xff0c;仅作参考。本人版本5.1。 参考视频&#xff1a; UE4热更新&#xff1a;HotPatcher插件使用教程_哔哩哔哩_bilibili 3.检查需要下载的版本_哔哩哔哩_bilibili 参考文章&#xff1a; UE 热更新&#xff1a;Questions &…