本篇文章,是基于我自用Linux系统中的自定义文件夹“test_rep”,当做示例演示
具体Git仓库的目录在:/usr/local/git/test_rep
Git基本操作
之前我们已经创建了 Git 版本库了,下一步我们将进行一些 Git 的基本操作。
有关 Git 版本库的知识点请参考:Git创建版本库
git status 查看仓库当前的状态
继续,我们已经成功地添加并提交了一个read.txt
文件,现在,是时候继续工作了,于是,我们继续修改read.txt
文件,改成如下内容:
$ vim read.txt
Git is a version control system.
Git is free software.#此处是我新增的一段文本
# :wq保存
现在,运行git status
命令看看结果:
$ 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: read.txt
no changes added to commit (use "git add" and/or "git commit -a")
git status
命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们,read.txt
被修改过了,但还没有准备提交的修改。如果想精简一下,可以使用git status -s
如果你忘记了具体修改了什么,或者是压根就不是你修改的,我们可以利用git diff
这个命令了。
git diff 比较文件的不同
利用git diff
这个命令查看文件修改了哪些:
$ git diff read.txt
diff --git a/read.txt b/read.txt
index 7f63a40..46d49bf 100644
--- a/read.txt
+++ b/read.txt
@@ -1 +1,2 @@
Git is a version control system.
+Git is free software.
diff 是 difference 的简写。上面的命令输出看到,刚才我添加了一行文本。此时知道了read.txt
作了什么修改,心里有数了,就可以把它提交到仓库中心了。
提交修改和提交新文件是一样的两步,第一步是git add
:
$ git add read.txt
此时可以利用git status
命令查看一下当前仓库的状态:
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: read.txt
很明显,上面的内容提醒你read.txt
作了修改,下一步就可以按照之前一样提交:
$ git commit -m 'append text'
[master b0259a8] append text
1 file changed, 1 insertion(+)
提交后,继续利用git status
命令查看一下当前仓库的状态:
$ git status
On branch master
nothing to commit, working tree clean
此时,Git 告诉我们当前没有需要提交的修改,而且,工作目录是干净(working tree clean)的。
git log 查看历史提交记录
继续由上面,我们再进行一次修改read.txt
文件如下:
$ vim read.txt
Git is a version control system.
Git is free software.
Git is a distributed.#此处是我新增的一段文本
# :wq保存
然后提交:
$ git add read.txt
$ git commit -m 'append new text'
[master fc9d399] append new text
1 file changed, 1 insertion(+)
像这样,你不断对文件进行修改,然后不断提交修改到版本库里,Git 每当文件commit
的时候就可以“保存一个快照”。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit
恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
此致,针对read.txt
文件一共有3个版本被提交到 Git 仓库里了:
第1个版本:
Git is a version control system.
第2个版本,增加了一行文本:
Git is a version control system.
Git is free software.
第3个版本,又增加了一行文本:
Git is a version control system.
Git is free software.
Git is a distributed.
这里只是简单的测试而已,但是实际工作中,谁知道你或者你的同事提交过多少次,具体提交的时候改的什么更不会记得了,此时我们可以利用git log
命令查看历史提交记录:
$ git log
commit fc9d399882b59e87920114579978e54cca018d13 (HEAD -> master)
Author: lee <lee@lee.com>
Date: Wed Nov 30 21:09:20 2022 +0800
append new text
commit b0259a82217775f384626ed7284a4d63f9fd177e
Author: lee <lee@lee.com>
Date: Wed Nov 30 21:00:45 2022 +0800
append text
commit 0fdd2240456285ba556d25f673da44cb01389958
Author: lee <lee@lee.com>
Date: Wed Nov 30 15:35:00 2022 +0800
append two files
#以上信息均是我本机的测试环境,还是得以你的测试环境对应即可
git log
命令显示从最近到最远的提交日志,我们可以看我这里的3次提交,最近的一次是刚刚提交的,注释为“append new text”。
如果嫌输出的信息太多,眼花不是不可能的,可以试试加上--pretty=oneline
参数:
$ git log --pretty=oneline
fc9d399882b59e87920114579978e54cca018d13 (HEAD -> master) append new text
b0259a82217775f384626ed7284a4d63f9fd177e append text
0fdd2240456285ba556d25f673da44cb01389958 append two files
以上展示的,就清爽多了。
再有,利用--reverse
参数来逆向显示所有日志:
$ git log --reverse --pretty=oneline
0fdd2240456285ba556d25f673da44cb01389958 append two files
b0259a82217775f384626ed7284a4d63f9fd177e append text
fc9d399882b59e87920114579978e54cca018d13 (HEAD -> master) append new text
还可以利用-author=用户名
查询指定用户的日志,甚至可以指定日期节点的命令:--since
和--before
,但是你也可以用--until
和--after
。
其中,有HEAD
标识的,代表次版本为当前最新版本。
需要友情提示的是,你看到的一大串类似fc9d39988...
的是commit id
(版本号),和 SVN 不一样,Git 的commit id
不是1,2,3……递增的数字,而是一个 SHA1 计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id
和我的肯定不一样,每个人的测试环境不同,到时候还得以你自己的为准。为什么commit id
需要用这么一大串数字表示呢?因为 Git 是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
git blame 查看指定文件的修改记录
从某种意义上说,git log
命令显示的所有操作的日志,其实我们还可以使用git blame
查看指定文件的操作日志,比如我们之前知道修改了read.txt
文件,我们可以直接查看该文件的日志:
#git blame 文件名
$ git blame read.txt
^0fdd224 (lee 2022-11-30 15:35:00 +0800 1) Git is a version control system.
b0259a82 (lee 2022-11-30 21:00:45 +0800 2) Git is free software.
fc9d3998 (lee 2022-11-30 21:09:20 +0800 3) Git is a distributed.
git blame
命令是以列表形式显示修改记录。
git reset 回退版本
现在,查看历史提交记录:
$ git log --pretty=oneline
#最后一步,当前版本,HEAD标识
fc9d399882b59e87920114579978e54cca018d13 (HEAD -> master) append new text
#上个版本
b0259a82217775f384626ed7284a4d63f9fd177e append text
#最初提交的两个文件
0fdd2240456285ba556d25f673da44cb01389958 append two filesv
首先,Git 必须知道当前版本是哪个版本,在 Git 中,用HEAD
表示当前版本,也就是最新的提交fc9d39988...
(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
现在,我们要把当前版本append new text
回退到上一个版本append text
,就可以使用git reset
命令:
$ git reset --hard HEAD^ #回退到上一个版本,HEAD^代表上一个版本
HEAD is now at b0259a8 append text #执行成功,显示当前的HEAD为“b0259a8 append text”
我们可以查看一下刚才read.txt
文件内容:
$ cat read.txt
Git is a version control system.
Git is free software.
由上面信息得知,最后一次追加的那帮文本"Git is a distributed.",已经回退没了,也被还原。
其实某种意义上,就类似指针似的,它再某个地址上,回退就像切换了某个指针地址。
下面我们详细解释一下git reset
命令,git reset
命令用于回退版本,也可以指定退回某一次提交的版本。
它的基本命令语法格式如下:
$ git reset [--soft | --mixed | --hard] [HEAD]
参数 | 功能 | 场景 |
---|---|---|
–hard | 清空工作区与缓存区 | 放弃目标版本后所有的修改 |
–soft | 保留工作区与缓存区,但是把版本之间的差异存放在缓存区 | 合并多个commit |
–mixed(或缺省) | 保留工作区清空缓存区,把版本之间的差异存放在工作区 | 1 有错误的commit需要修改 2 git reset HEAD清空缓存区 |
git reset
命令可以指定不同的回退方式:
#例如
$ git reset HEAD^ # 回退所有内容到上一个版本
$ git reset HEAD^ read.txt # 回退read.txt文件的版本到上一个版本
$ git reset 0fdd224 # 回退到指定版本,也就是commit id,不用写全,但是要尽可能长点,个人习惯写6-7位
git reset
命令涉及到了一些 Git 的工作区、缓存区和版本库之间的关系,所以实现理解一下 Git 的工作区、缓存区和版本库是有必要的,我在前面的博文里已经简单的阐述过。这里我简单的给一个图例:
git reset --mixed(默认)
- 移动本地库HEAD指针
- 重置暂存区
- 意思就是,回滚后,不仅移动了本地库的指针,同时暂存区的东西也没了,意思就是你上次添加到暂存区的文件没了
git reset --soft
- 移动本地库HEAD指针
- 意思就是,回滚后,仅仅是把本地库的指针移动了,而暂存区和你本地的代码是没有做任何改变的。而你上次改动已提交committed到本地库的代码显示是绿色即未提交
git reset --hard
- 移动本地库HEAD指针
- 重置暂存区
- 重置工作区
- 意思就是,回滚后,本地代码就是你回退版本的代码
从上面的解析看来,刚才我用的是**–hard**,更像是一劳永逸的回退,直接回退到底了。
至于有人问,能不能再回退回去?答案是肯定的,前提你知道之前的“commit id”,可以直接通过指定“commit id”回退,从而起到回退回去的操作。之前的窗口关了,记不得了?那我也没啥办法,搜搜网络吧,作者本人也没研究过,毕竟谁没事干回退来回退去啊。