欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > Git之提交和撤销操作

Git之提交和撤销操作

2025/1/11 14:22:08 来源:https://blog.csdn.net/xjjxjy_2021/article/details/144974670  浏览:    关键词:Git之提交和撤销操作

文章目录

  • 前言
  • 一、工作区、暂存区和版本库的概念
    • 1.介绍
    • 2.它们之间的关系
  • 二、命令介绍
    • 1.git add
    • 2.git commit
    • 3.git log
    • 4.git status
    • 5.git diff
    • 6.git reset
    • 7.git reflog
    • 8.git checkout
    • 9.git rm [file]
  • 三、.git目录
  • 总结


前言

本文从工作区,暂存区和版本库的概念引入, 介绍了Git中的一些基础命令, 同时结合实例来学习如何将文件提交到git仓库,以及如何进行撤销修改等操作.


一、工作区、暂存区和版本库的概念

1.介绍

工作区: 我们在电脑上修改的代码文件所在的目录,简单来说就是你对代码进行修改的地方;
暂存区(stage|index): 一般是位于.git目录下的index文件中,我们也称之为索引。需要先将待提交的文件添加到暂存区,然后再提交到版本库;
版本库(repository): 又名仓库,位于工作区的隐藏目录.git中,它不属于工作区,而是独立出来的Git的版本库。版本库中将每一次git提交作为一个Git对象进行管理,每个文件的修改、删除都会被跟踪,以便在后续开发中对历史记录进行查看或者“还原”。

2.它们之间的关系

工作区、暂存区、版本库之间的关系可以参考下图
在这里插入图片描述

  1. 当创建Git版本库时,Git会自动创建一个唯一的master分支,以及指向master分支的HEAD;
  2. 当对工作区修改的内容(增/删/改文件)执行git add命令时,暂存区目录树的文件索引会被更新;
  3. 当执行git commit提交命令时,master分支会进行对应的更新,即将暂存区的目录树真正写入到版本库中。

总结来说,我们在工作区进行增删改文件等操作不会同步更新到仓库中,只有使用git addgit commit命令后,才能将修改提交到仓库中进行管理。

二、命令介绍

1.git add

git add [file1] [file2] [file3] #添加一个或多个文件 到暂存区
git add [dir] 					#添加指定目录(及其子目录) 到暂存区
git add							#添加当前目录下所有文件改动 到暂存区

2.git commit

git commit -m "commit message" #提交修改内容到版本库,-m后跟上本次提交的具体描述,方便后续回顾历史记录

注意: message绝对不能省略,要描述你的提交细节,方便后续维护。
举例:
创建文件code1,在文件中写入内容为"git add",通过git add命令将code1文件添加到暂存区,再使用git commit命令将暂存区的内容提交到版本库中。
在这里插入图片描述
可以看到git commit命令的提示信息中说明:一个文件被修改(新增的文件code1),插入了一行内容(在code1中写入的"git add")。
也可以尝试add多个文件,然后一次commmit提交所有文件:
在这里插入图片描述
git commit是将暂存区中所有的修改提交到版本库中。
参考下面的例子,我们创建文件code5,然后使用命令git add code5将它添加进暂存区,接着创建code6,最后执行git commit -m "msg"将暂存区中的修改提交到版本库。可以看到,提交信息上显示的是1个文件被修改,即只提交了code5的修改,因为code6的修改没有被添加到暂存区中。
在这里插入图片描述
如果需要将code6的修改也提交到版本库,可以重复上面的过程,先执行git add,再执行git commit即可。
在这里插入图片描述

3.git log

git log #查看提交历史记录
git log --pretty=oneline #将日志信息精简为一行

在这里插入图片描述
可以看到我们先前进行的两次提交的日志信息,带上–pretty=oneline选项可以精简提交的日志信息为一行。
在这里插入图片描述
日志信息中commit后面跟着的一串乱码,实际上是每次提交的commit id(可以理解为版本号),是Git用于唯一标识某次提交的。commit id并非1,2,3,…依次递增的数字,而是通过计算得到的一个很大的数字,用十六进制表示。

commit id是由40位的SHA-1哈希值组成的,它是通过将提交内容和提交信息(比如作者、时间等)进行哈希函数处理后生成的。

4.git status

git status #查看最近一次提交后,当前对于文件的修改

在这里插入图片描述
提示信息告诉我们工作区的code2文件被修改过,但是还未完成添加到暂存区和提交到版本库等操作。
将修改添加到暂存区后,再执行git status可以看到:
在这里插入图片描述
最后执行git commit命令后,使用git status命令就显示没有修改了:
在这里插入图片描述

5.git diff

通过git status命令我们只能查看到修改了那些文件,但是无法获取到具体修改的内容。如果修改的代码量过大,不便于我们进行查看和修改,通过git diff命令可以查询到当前修改的内容。

git diff [文件名] #查看暂存区和工作区文件的差异
git diff HEAD -- [file] #查看版本库和工作区文件的差异

在这里插入图片描述
显示信息的格式是Unix通用的diff格式:

a/code2 是修改前对应文件;
b/code2 是修改后对应文件;
--- 是删除;
+++ 是添加;

将修改添加到暂存区后,执行git diff [code2]可以发现没有显示差异,再执行git diff -- [code2]后可以看到版本库和工作区之间的差异:
在这里插入图片描述
最后执行git commit命令后,使用git diff命令就不会显示差异了:
在这里插入图片描述

6.git reset

在我们实际开发过程中,会出现需要从历史的某个版本重新开发的情况,这时就需要用到git的版本回退功能了.
git reset命令可以指定回退到某次提交的版本.

git reset [--soft|--mixed|--hard] [HEAD] [file]#版本回退

举例:将代码回退到上一个版本
在这里插入图片描述
在这里插入图片描述

注意: 回退的本质是将版本库中的内容回退, 工作区或暂存区内容是否回退取决于配置的命令参数.

–soft 选项是将版本库回退到指定版本, 而暂存区和工作区内容保持不变.
–mixed 为默认选项, 即不带参数时相当于带这个选项. 该选项是将暂存区和版本库的内容回退到指定版本内容, 而工作区保持不变
–hard 选项是将工作区、暂存区和版本库都回退到指定版本. 注意: 当工作区有尚未提交的代码时谨慎使用这个命令, 因为一旦工作区回滚, 未提交的代码就再也找不回来了.
HEAD 选项用于指定回退的版本, 也可以写成指定版本的commit id.
HEAD表示当前版本(版本指的是版本库的版本);
HEAD^表示上一个版本;
HEAD^^表示上上一个版本;
以此类推.
也可以使用~数字的形式指明版本:
HEAD~0表示当前版本;
HEAD~1表示上一个版本;
HEAD~2表示上上一个版本;
以此类推.
file 可以指定要回退的具体文件file,没有指定则默认回退所有修改的文件。

7.git reflog

当我们回退到历史版本version2后, 又想重新回到该历史版本之后的版本version3该怎么办? 同样是使用 git reset命令, 但是必须要获取到对应版本的commit id。然而, 如果并非即时的进行版本回退,从上方的命令行中获取commit id,则此时无法获取到该版本的commit id。
下图可以看到再使用git log是无法打印出version2之后的版本信息(commit id)。
在这里插入图片描述
可以看到日志中最新的是当前版本的信息,无法查询到change code2的版本信息了。

这时可以使用git reflog命令:

git reflog #查看本地执行的所有git命令

通过这条命令可以找到本地所有的操作记录。
在这里插入图片描述
在这里插入图片描述

在实际操作中,我们会发现Git的版本回退非常快, 这是因为Git的版本回退本质是在Git里面有一个指向当前分支的HEAD指针(前文说过, HEAD指针是指向master的,而master是存储了最近一次提交的commit id). 当我们进行版本回退时,本质是将master中存储的commit id改成了指定版本的commit id,因此速度会很快。

8.git checkout

上文中的git reset命令主要是对于版本库文件的回退版本来说的,如果我们在工作区进行了较长时间的修改, 但是目前不想要这些修改, 想恢复到上一个版本应该如何做?
当改动较小,则可以尝试用git diff命令来查看当前工作区的修改,然后将修改重置回去。但是,当改动较多,此时手动一个个改回去就不太现实,耗时量大并且容易将代码改出bug,因此可以使用git checkout --命令来将文件直接恢复到最近一次add/commit的状态。

git checkout -- [file] #将工作区指定文件恢复到最近一次add/commit的状态

在这里插入图片描述
在这里插入图片描述

注意:只有携带--时, 该命令才是这个功能, 该命令的其他选项及其对应功能会在后续文章中进行介绍。

如果在工作区修改的内容还未add到暂存区,则可以使用命令git checkout -- [file]将指定文件恢复到最近一次add/commit的状态.
如果工作区修改的内容已经add到暂存区了或者已经commit到版本库了, 我们想要丢弃工作区当前的修改, 则可以参考前文的命令来进行撤销修改.

  1. add到暂存区的情况:
    使用git reset [--mixed] HEAD [file] 命令, 可以将暂存区的内容回退到当前版本(当前版本库的版本)。然后,再使用git checkout -- [file]将工作区的修改回退到当前版本
    或者直接使用git reset --hard HEAD [file]命令,将暂存区和工作区的修改都回退到当前版本。
  2. commit到版本库的情况:
    使用git reset --hard HEAD^命令, 可以将工作区和暂存区的内容回退到上一个版本。
    注意, 这种操作的前提是你还没有将自己的本地仓库的修改push到远程仓库,也就是commit之后还没有push。
    我们进行撤销的目的,就是避免有问题的代码影响到远程仓库!!!只有被push到远程仓库之前的撤销才是有效的

9.git rm [file]

git rm [file] #将暂存区中的文件file删除

当我们需要从版本库中删除某个文件file时,可以执行以下步骤:

  1. 执行rm file命令将工作区的file文件删除,此时使用git status可以看到有一个修改待add和commit。
    在这里插入图片描述
  2. 然后执行git add file命令,将工作区中删除file的这个修改添加到暂存区中,此时使用git status可以看到有一个修改待commit。
  3. 最后执行git commit -m "rm file"将暂存区中的修改提交到版本库中,至此版本库中的file文件就被删除了。
    在这里插入图片描述

当然,git为我们提供了一种更简化步骤的命令 git rm,步骤简化为:

  1. 执行git rm [file]命令,可以将工作区中的file命令删除,同时将这个修改添加到暂存区中,此时使用git status可以看到有一个修改待commit。
  2. 然后执行git commit -m "git rm file"将暂存区中的修改提交到版本库中,至此版本库中的file文件就被删除了。
    在这里插入图片描述

三、.git目录

使用命令tree .git 查看.git目录的子目录
在这里插入图片描述
在这里插入图片描述
子目录的介绍:

  1. .git 目录下的index就是暂存区,执行git add后会将对应的Git对象索引添加到index中。
  2. HEAD 是默认指向master分支的指针:
    在这里插入图片描述
    我们再查看master中的内容:
    在这里插入图片描述
    可以看到master中保存的内容和最新一次的commit id是相同的,即master中保存的是当前最近一次的commit id。
  3. objects 是Git的对象库,其中存储了所创建的各个版本库对象及其内容。当我们执行git add命令时,工作区中对文件内容进行的修改会被创建出的Git对象记录,并写入objects目录下,同时暂存区内对应的目录树会被更新。
    在这里插入图片描述
    可以看到在我们进行了几次提交后,objects目录下多了几个子目录,子目录的名称实际上是我们每次commit得到的commit id的前两位数,而子目录下的文件的文件名则是commit id的后38位。
    在这里插入图片描述
    由于版本库对象对应的文件是经过sha(安全哈希算法)加密过的,所以我们无法直接查看该文件的具体内容,但是可以使用命令git cat-file来查看版本库对象的内容:
    在这里插入图片描述
    可以看到版本库对象中记录了提交人信息,提交描述以及两个特殊的commit id。
    其中,parent 对应的是当前版本库对象对应的提交的上一次提交的commit id:
    在这里插入图片描述
    tree 对应的是当前所有提交的记录:
    在这里插入图片描述

总结

以上就是今天要讲的内容,本文介绍了 的相关概念。本文作者目前也是正在学习C++相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。
最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com