本地仓库管理

查看仓库状态

上一篇文章中,我们新建了 README.md 文件,现在我们运行 git status 命令查看工作区状态!

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

可以看到,给出的提示 nothing to commit, working tree clean 表示没有可提交的,工作区很干净
然后,我们尝试修改文件,然后再使用 status 命令···

image.png

image.png

可以在截图中看到,现在显示为 modifiled: README.md ,以上的输出就是告诉我们 README.md 文件被修改过了,但是还没有准备提交修改(use "git add <file>..." to update what will be committed) 提示可以使用 git add 命令提交文件。
虽然我们知道文件被修改了,但是具体修改了什么内容,我们需要使用 git diff 命令去查看:

$ git diff READEME.md
diff --git a/READEME.md b/READEME.md
index 6668511..9ea6648 100644
--- a/READEME.md
+++ b/READEME.md
@@ -1 +1,2 @@
-1 我现在新创建了文件
\ No newline at end of file
+1 我现在新创建了文件
+2 这是我的第二次修改
\ No newline at end of file

在知道修改内容是什么了以后,我们再提交就会放心很多。好了,既然我们要提交修改,那么提交修改和提交新文件的方式是一样的,同样是分两步 git add 然后 git commit

$ git add READEME.md

当我们再使用 git status 命令,就可以看到,系统提示和刚刚不一样了,显示有待提交的文件

image.png

$ git commit -m "这是我第二次修改"

总结

通过本章的学习,了解了 git status 命令和 git diff 命令的使用,在不清楚仓库状态的情况下,建议先用 git status 命令查看仓库状态,如果有未提交的内容,就可以使用 git diff 命令查看到底修改了什么!

版本回退

接着上面的内容,我们知道了怎么将修改的文件进行提交。但是问题接踵而至,如果我们手贱,一不小心提交了本不应该提交的东西呢?
好的,首先重温一遍,修改和提交操作,毕竟温故而知新嘛!


然后把命令敲起来

$ git add *
$ git commit -m "这是我第三次修改"
[master 9330256] 这是我第三次修改
 1 file changed, 2 insertions(+), 1 deletion(-)

像这样,我么不断的修改文件,然后不断的提交到版本库里面,就好像是玩实况足球的世界杯一样,每打完一场比赛,都会自动进行存档,这样,如果某场淘汰赛输掉了,还可以找到之前保存的游戏节点,从指定的节点进行恢复。git 也是一样的,当你每一次 commit 的时候,都保存了一份快照。一旦你把文件改乱了 ,或者误删除了,都可以从你指定的 commit 节点恢复,然后继续工作,而不会丢失大量的工作成果!
好的,我们现在来回顾下,README.md 一共进行了几次提交


从截图看,我们一共提交了 3 次,但是对于生产环境来说,我们怎么可能记得那么清楚,那么我们可以利用 git log 命令,来查看仓库的日志!

$ git log
commit 9330256da5ec7e696beb194274e9e1f528b27aa2 (HEAD -> master)
Author: 蜂*煤 <4191***61@qq.com>
Date:   Tue Feb 4 14:45:45 2020 +0800

    这是我第三次修改

commit d5c313f5d8d981891240282ad6f0b690535a6e71
Author: 蜂*煤 <4191***61@qq.com>
Date:   Mon Feb 3 21:04:02 2020 +0800

    这是我第二次修改

commit 9d457b57421386945f1b754765a7052dacf10dce
Author: 蜂*煤 <4191***61@qq.com>
Date:   Sun Feb 2 14:34:04 2020 +0800

    这是我的第一次提交

从上面,我们可以很清晰的看出来我们仓库整个提交日志

需要友情提示的是,你看到的一大串类似1094adb...的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。

好的,我么现在假象一个场景,我 第三次提交 是一次误提交,我现在想回到第二次修改那个节点。那到底该怎么做呢?
首先,你必须知道当前是哪个版本,在 GIT 中,用 HEAD表示当前版本,也就是最新提交的 9330256.....,上一个版本可以写为 HEAD^,同理,上上个版本就可以写成 HEAD^^ ,但是我们想回退到前10个版本时,这样写,就显得很不合适了,所以有另一种写法,前10个版本写为 HEAD~10.
那么,现在我们尝试将文件恢复到第二次修改时的状态!

rp@DESKTOP-BVB5IBJ MINGW64 /d/gitRepositoryTest/test_rep1 (master)
$ git reset --hard HEAD~1
HEAD is now at d5c313f 这是我第二次修改

在执行 git reset --hard HEAD~1 命令后,有明确的提示 HEAD is now at d5c313f 这是我第二次修改 。我们在看看文件内容。

我们再看看日志!可以清晰的看到,和恢复前相比,git reset --hard 连提交日志都没有保留。

$ git log
commit d5c313f5d8d981891240282ad6f0b690535a6e71 (HEAD -> master)
Author: 蜂窝煤 <419105961@qq.com>
Date:   Mon Feb 3 21:04:02 2020 +0800

    这是我第二次修改

commit 9d457b57421386945f1b754765a7052dacf10dce
Author: 蜂窝煤 <419105961@qq.com>
Date:   Sun Feb 2 14:34:04 2020 +0800

    这是我的第一次提交

文件成功的恢复到了 “第二次修改” 的状态,那么问题又来了,我现在虽然恢复了,但是我想反悔,该怎么办?ヾ|≧_≦|〃
没有关系,在 GIT 的世界里,都是有后悔药吃的。
我们可以使用命令 git reflog

d5c313f (HEAD -> master) HEAD@{0}: reset: moving to HEAD~1
9330256 HEAD@{1}: reset: moving to HEAD
9330256 HEAD@{2}: reset: moving to HEAD
9330256 HEAD@{3}: commit: 这是我第三次修改
d5c313f (HEAD -> master) HEAD@{4}: commit: 这是我第二次修改
9d457b5 HEAD@{4}: commit (initial): 这是我的第一次提交

从输出可以看到,开头的便是 commit id ,我们可以通过 commit 的 id ,再利用 reset --hard commit-id 恢复到指定的 commit 节点!我们来试试吧ヽ(=・ω・=)丿

$ git reset --hard 9330256
HEAD is now at 9330256 这是我第三次修改

根据提示可以看到,HEAD is now at 9330256 这是我第三次修改 ,那么我们再康康日志和文件呢?是不是我们预期的呢?

$ git log
commit 9330256da5ec7e696beb194274e9e1f528b27aa2 (HEAD -> master)
Author: 蜂窝煤 <419105961@qq.com>
Date:   Tue Feb 4 14:45:45 2020 +0800

    这是我第三次修改

commit d5c313f5d8d981891240282ad6f0b690535a6e71
Author: 蜂窝煤 <419105961@qq.com>
Date:   Mon Feb 3 21:04:02 2020 +0800

    这是我第二次修改

commit 9d457b57421386945f1b754765a7052dacf10dce
Author: 蜂窝煤 <419105961@qq.com>
Date:   Sun Feb 2 14:34:04 2020 +0800

    这是我的第一次提交
image.png

是的,他胡汉三又回来了。通过上面的操作我们得出一个结论。HEAD 表示目前最新的节点的指针reset --hard 实际上就是在操作指针,改变 HEAD 的指向。通过下面两张图,我们感受一下

reset1.gif

reset2.gif

总结

版本回顾,命令的话,正确掌握 reset 命令就可以了,关键是要理解 HEAD 的意思。
git log 用于查询仓库当前,及以前的 commit 节点
git reflog 用于查询仓库所有操作节点的记录(包含 reset 信息)。

工作区 > 暂存区 > 仓库

GIT 和其它版本控制工具不同之处之一就是有暂存区的概念。

我们先看看一个个的看

工作区(working directory)

就是我们目前在命令行中,敲命令的这个目录D:\gitRepositoryTest\test_rep1

工作区

暂存区

我们先看下面这张图


可以从图中看到,暂存区(stage)就是当工作区修改或者新增文件后,使用 git add 命令,将文件的改动添加到暂存区中。下面我们通过实例来验证一下。

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

在什么都没有修改的情况下,使用 git status 查看版本库状态,显示 nothing to commit, working tree clean ,然后我们修改文件

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

当使用 git add 命令后,修改就被提交到了暂存区,接下来就可以通过 git commit 命令将修改提保存为快照。

$ git commit -m "第四次修改,将保存为快照"
[master 30bc24b] 第四次修改,将保存为快照
 1 file changed, 2 insertions(+), 1 deletion(-)

当我们再使用 git status 命令时,就会出现以下提示:

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

通过上面的图和操作,我们有了三个工作区域的概念,既:工作区 > 暂存区 > 仓库(.git),通过三个工作区域的概念,又引申出3种状态

三种状态

Git 有三种状态,你的文件可能处于其中之一:已修改(modified)和已暂存(staged)、已提交(committed)、。 已提交表示数据已经安全的保存在本地数据库中。 已修改表示修改了文件,但还没保存到暂存区中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

总结

总而言之,言而总之,我们要理解 git 工作的3个基本步骤。

  1. 修改、增加文件(modified)
  2. 提交到暂存区(staged) 命令:git add
  3. 保存快照(committed) 命令:git commit

管理修改

通过上面的学习,理解了暂存区的概念。实际上 git 个其它版本管理很不一样的一点,就在于GIT跟踪管理的并不是文件,而是管理的修改。其实也可以理解为,你的每一次操作,git 都将你的操作保存到数据库,然后根据命令进行操作。
通过下面的操作,我们来看看:


$ git add READEME.md

rp@DESKTOP-BVB5IBJ MINGW64 /d/gitRepositoryTest/test_rep1 (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   READEME.md

先用 add 命令添加到暂存区中(stage) ,然后再次修改文件,并且执行 commit 命令!

$ git commit -m "提交第五行"
[master ee7e249] 提交第五行
 1 file changed, 2 insertions(+), 1 deletion(-)

rp@DESKTOP-BVB5IBJ MINGW64 /d/gitRepositoryTest/test_rep1 (master)
$ 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:   READEME.md

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

都说透过现象看本质,我们就通过上面的一些列操作,来剖析下,git 是如何跟踪管理修改的。

可以看到,我们又在文件中添加了第6行,然后执行了 commit 命令,接下来,执行了 status 命令,然后发现,我们的工作区依然提示有未提交的。ヽ(●-`Д´-)ノ
但是不要惊讶,通过我们之前描述的概念,其实不难发现,commit 命令实际上只会将暂存区的修改进行提交(保存快照)。因为我们新增的第6行并没有提交到暂存区,所以 commit 不会提交这次的修改。

总结

通过此章,我们更加细致的跟踪了 git 对修改的管理。同时也是在加强对暂存区的理解!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 工作流程 首先需要说明的是,git的版本库是以分支的形式进行管理的。当我们初始化一个新的版本库时,会自动创建版...
    happy_19阅读 2,789评论 0 1
  • 以下笔记主要参考gitgot,大致了解git使用和原理。 第一部分我们从个人的视角去研究如何用好Git,并且揭示G...
    carolwhite阅读 2,453评论 0 1
  • 大纲: 一、前言 二、概述 三、在Windows上安装Git 四、创建本地仓库 五、本地仓库管理详解 六、总结 注...
    首席架构师阅读 378评论 1 3
  • 一、基本概念: 注:对于git的分布式概念及其优点,不重复说明,自己百度或谷歌。本文中涉及到指令前面有$的,在cm...
    大厂offer阅读 1,488评论 0 3
  • Add & Commit git init 初始化一个 Git 仓库(repository),即把当前所在目录变成...
    冬絮阅读 4,974评论 0 9