第二讲:Git删除、修改、撤销操作

前言
在第一讲中我们对Git进行了简单的入门介绍,相信聪明的你已经了解Git的基本使用了。
Git应用详解第二讲:Git删除、修改、撤销操作_第1张图片

这一讲我们来进一步深入学习Git应用,着重介绍Git的一些常见操作,包括:删除文件、比较文件、撤销修改、修改注释与查看帮助文档。

一、删除文件
1.git rm
「该命令用于删除版本库中的文件」;删除工作区和暂存区中的文件都会报错:

若用该指令删除「工作区」中的文件,会报找不到文件的错误:
Git应用详解第二讲:Git删除、修改、撤销操作_第2张图片
若用该指令删除「暂存区」中的文件,报如下错误:
Git应用详解第二讲:Git删除、修改、撤销操作_第3张图片

「所谓版本库中的文件指的是」:已经通过commit指令提交的文件,而不是工作区中的文件(「红色」),或暂存区中的文件(「绿色」)。


git rm完成了两步操作:

「第一步」:将版本库中的文件删除;
「第二步」:将删除操作纳入暂存区(stage)。如下图所示,相当于执行了git add test.txt,随后可直接提交,完成test.txt的删除;
Git应用详解第二讲:Git删除、修改、撤销操作_第4张图片
2.rm
「该命令用于删除工作区和版本库中的文件,不能删除暂存区文件」;


「注意」:没有添加到git仓库中的本地文件,都属于工作区文件。


删除「工作区」中的文件时:
Git应用详解第二讲:Git删除、修改、撤销操作_第5张图片
删除「版本库」中的文件时:
Git应用详解第二讲:Git删除、修改、撤销操作_第6张图片
与git rm「不同的是」,该指令不会将删除操作纳入「暂存区」。需要先将删除的test.txt纳入「暂存区」,再提交到「版本库」才能完成test.txt文件的删除;

删除「暂存区」中文件时:
Git应用详解第二讲:Git删除、修改、撤销操作_第7张图片
从图中可知rm命令只能删除工作区中的test3.txt,不能删除暂存区中的test3.txt;:

二、重命名文件
1.git mv
使用git命令git mv:

git mv test.txt test3.txt
将test.txt重命名为test3.txt;mv命令可理解为「剪切」的同时进行「更名」;
Git应用详解第二讲:Git删除、修改、撤销操作_第8张图片

changes to be committed 表示该修改已经纳入「暂存区」,可以进行提交操作;


一般「绿色」的文件(操作)表示已经提交到「暂存区」了,不用再进行git add ,可以直接进行提交(git commit)。


从上文可知git mv做了两件事:

「第一步」:将文件test.txt重命名为test3.txt;
「第二步」:将重命名操作test.txt -> test3.txt纳入「暂存区」;
2.mv
使用系统命令mv:

mv test2.txt test3.txt
执行该语句后查看状态git status:
Git应用详解第二讲:Git删除、修改、撤销操作_第9张图片

发现工作区中多出两步操作:

删除文件test2.txt;

新建文件text3.txt;

再使用git add test2.txt test3.txt 将操作提交到暂存区,通过git status查看状态:
Git应用详解第二讲:Git删除、修改、撤销操作_第10张图片

此时git立即就能识别出来这是一个文件重命名;

「由此说明git mv进行了三步操作:」

「第一步」:删除工作区中重命名前的文件test2.txt;
「第二步」:在工作区中创建重命名后的文件test3.txt;
「第三步」:将上述的两个操作提交到「暂存区」中;
即git mv 与 mv的区别相当于git rm 与 rm 之间的区别。

三、比较文件
1.本地文件 <-> 本地文件
diff file_a file_b
这是系统提供的比较命令,用于比较本地文件或已经提交到版本库的文件。创建文件a和文件b,使用上述指令进行比较:

Git应用详解第二讲:Git删除、修改、撤销操作_第11张图片
「在 diff -u a b的输出信息中:」


加上参数-u可以更详细地显示比较信息。


--- a表示a为原文件;

+++ b表示b为目标文件;

「-1,3「中 「-」 表示原文件即a,」1」 表示原文件中的第一行,「3」 表示到第3行。合起来的意思为:「在原文件a中的1~3行」;

同理:「+1,3」 表示:「目标文件b中的1~3行」;

数据前面「有三种符号」,分别表示不同的信息:

所以整个输出信息的意思为:AABB这一行两文件都有,只要原文件a去掉:

「空格」:表示该行在两个文件中都存在,如上图所示AABB这一行文件a,b都有;
「-」 :表示原文件a去掉该行就能变为目标文件b;
「+」 :表示原文件a加上该行就能变为目标文件b;
a1
a2
并加上:

b1
b2
就能变为目标文件b;

2.工作区 <- 暂存区
以下为git提供的比较命令,作用为:比较「暂存区」和「工作区」中的同一文件。并且:「原始文件」为「暂存区」中的文件,「目标文件」为「工作区」中的文件。示例如下:

git diff
首先,新建文件A.txt和B.txt,修改其内容并提交到「暂存区」:

Git应用详解第二讲:Git删除、修改、撤销操作_第12张图片
然后,在「工作区」中再次修改文件A.txt与B.txt的内容:
Git应用详解第二讲:Git删除、修改、撤销操作_第13张图片

此时使用git diff进行比较:

Git应用详解第二讲:Git删除、修改、撤销操作_第14张图片
「在 git diff的输出信息中:」

--- a/A.txt:表示「原文件」为「暂存区」中的A.txt;

+++ b/A.txt:表示「目标文件」为「工作区」中的A.txt;

-1:其中-表示原文件,1表示从第1行开始。由于暂存区中的A.txt文件(「原文件」)只有1行,所以将原来的(-1,1)简写为-1;

+1,2:其中+表示目标文件,1,2表示工作区中的A.txt文件(「目标文件」)从第1行开始有2行;

hello world:表示「原文件」和「目标文件」中都存在的内容;

+hello java表示暂存区中的A.txt加上该行,就能变得与工作区中的A.txt一样;

可以看到该指令是将同一文件的「工作区」版本与「暂存区」版本进行比较,各比各的,并不会将A.txt与B.txt进行比较。

3.工作区 <- 版本库
以下指令作用为:比较「版本库」和「工作区」中的同一文件。并且:「原始文件」为「版本库」中的文件,「目标文件」为「工作区」中的文件。

git diff commit_id
用于比较指定commit id提交上的A文件和工作区中的A文件;

git diff HEAD
用于比较最新提交上的A文件和工作区中的A文件:


上面的A文件仅为一个示例,以下同理。


如下图所示,先初始化test.txt为:版本库中的修改,然后进行一次提交;随后在工作区中为test.txt添加工作区的修改;然后执行上述比较指令,从显示出来的比较结果可知,工作区中的test.txt文件比最新一次提交的test.txt文件多了一行工作区中的修改内容。
Git应用详解第二讲:Git删除、修改、撤销操作_第15张图片

4.暂存区 <- 版本库
以下指令作用为:比较「版本库」和「暂存区」中的同一文件,其中「原始文件」为「版本库」中的文件,「目标文件」为「暂存区」中的文件:

git diff --cached commit_id
用于比较指定提交上的A文件和暂存区中的A文件;

git diff --cached
用于比较最新提交上的A文件和暂存区中的A文件。示例如下:
Git应用详解第二讲:Git删除、修改、撤销操作_第16张图片

可以看到,暂存区中的A.txt文件比最新提交中的A.txt文件多了一行hello java;暂存区中的B.txt文件比最新提交中的B.txt文件多了一行hello java2。

5.总结
关于目标文件与原始文件的判定,遵循的顺序为:工作区 <- 暂存区 <-版本库(提交);

上述比较指令的比较如下表所示:

指令 作用 原始文件 目标文件
diff 比较两个本地文件 本地文件/版本库 本地文件/版本库
git diff 比较暂存区和工作区中的同一文件 暂存区 工作区
git diff commit_id 比较指定commit id提交上的A文件和工作区中的A文件 版本库 工作区
git diff HEAD 比较最新提交上的A文件和工作区中的A文件 版本库 工作区
git diff --cached commit_id 比较指定提交上的A文件和暂存区中的A文件 版本库 暂存区
git diff --cached 比较最新提交上的A文件和暂存区中的A文件 版本库 暂存区

表格中的A文件仅为示例。


四、撤销修改
主要是将已经纳入「暂存区」的修改(「绿色」),先恢复到「工作区」(「红色」),再恢复到修改前。比如撤销git rm这一删除操作:

1.将暂存区修改恢复到工作区(unstage)

也就是将对文件的修改操作由「绿色」变为「红色」。


法一:git reset head
如下图所示,通过git rm删除了版本库中的test3.txt文件,并将该操作提交到了暂存区。随后通过以上命令,将这一删除操作恢复到了工作区;
Git应用详解第二讲:Git删除、修改、撤销操作_第17张图片

法二:git restore --stage
这里的参数--stage写成--staged效果是一样的,作用与法一相同:
Git应用详解第二讲:Git删除、修改、撤销操作_第18张图片

2.撤销工作区操作
比如撤销工作区中对文件的修改、新增和删除操作:

法一:git restore
如下图所示,在工作区中删除了test3.txt文件。然后,通过上述指令撤销了工作区中对test3.txt的删除操作:
Git应用详解第二讲:Git删除、修改、撤销操作_第19张图片

法二:git checkout --
作用与法一相同:

Git应用详解第二讲:Git删除、修改、撤销操作_第20张图片
五、修改提交注释与作者
1.修改最近一次提交信息
git commit --amend -m '修正信息'
如果写错了提交消息:
Git应用详解第二讲:Git删除、修改、撤销操作_第21张图片

可以通过:git commit --amend -m '注释' 来修改「上一次」的提交信息:(amend是修复的意思)

Git应用详解第二讲:Git删除、修改、撤销操作_第22张图片
git commit --amend
当需要为最近一次提交添加大量注释时,可以直接使用该指令进入vim编辑器编辑:
Git应用详解第二讲:Git删除、修改、撤销操作_第23张图片
Git应用详解第二讲:Git删除、修改、撤销操作_第24张图片

这样的好处是:错误的提交和修正后的提交经过该命令修正后,只变为「一次提交」,而不是两次提交;

git commit --amend --author 'Name'
用于修改最近一次提交的配置信息,包含作者和注释信息。执行命令时会进入vim编辑器编辑注释信息:

Git应用详解第二讲:Git删除、修改、撤销操作_第25张图片
修改前该分支上最近两次的提交信息为:

Git应用详解第二讲:Git删除、修改、撤销操作_第26张图片
修改后的最近两次提交信息为:
Git应用详解第二讲:Git删除、修改、撤销操作_第27张图片

可以看到成功地改变了最新一次提交的作者和提交注释。


「注意」:修改提交注释的同时,虽然提交的内容相同,但是提交前后的commit_id是不同的,说明创建了一个新提交替换了原来需要修正的提交。如下图中的提交5与提交3所示:
Git应用详解第二讲:Git删除、修改、撤销操作_第28张图片


2.修改特定提交信息
如图所示,在test分支进行了四次提交。现在我们想要修改第三次提交的提交信息:
Git应用详解第二讲:Git删除、修改、撤销操作_第29张图片

git rebase -i commit_id
通过以上指令可以进入rebase交互模式,并显示commit_id之后的提交信息。比如:若命令中的commit_id为第一次提交的commit_id,那么就会显示第2~4次的提交信息。这里我们需要修改第三次提交的信息,只需要将它指定为第二次提交的commit_id即可。执行以下命令,进入vim编辑器:

git rebase -i 678e0
Git应用详解第二讲:Git删除、修改、撤销操作_第30张图片
在这个界面中,我们可以通过将pick参数修改为其他rebase提供的参数,从而对第三次错误提交进行修改。有两个参数可以实现这一目的:


这里涉及到vim编辑器的使用方式:

shift + A为插入命令,可进入vim编辑器的编辑模式;
编辑完成后,先按ESC回到vim编辑器的命令行模式,再输入:wq表示保存并退出编辑器;

「reword参数」

该参数的意思是:直接修改设置了该参数的提交的提交注释。这里应该将第三次提交的pick参数改为reword:
Git应用详解第二讲:Git删除、修改、撤销操作_第31张图片

通过:wq保存并退出,随后再次进入vim编辑器,这次是修改设置了reword参数的提交的提交注释:
Git应用详解第二讲:Git删除、修改、撤销操作

将它改为正确的提交信息:
Git应用详解第二讲:Git删除、修改、撤销操作

通过:wq保存并退出vim编辑器,完成错误提交信息的修改,再次查看历史提交信息:
Git应用详解第二讲:Git删除、修改、撤销操作_第32张图片

可以发现:错误的提交信息得到了纠正,并且这次提交及其之后的提交的commit_id都发生了变化。说明git新创建了对应数目的提交,并对原有提交进行了覆盖,但是内容没有发生变化;


事实上:rebase的含义为变换基准,git rebase -i commit_id中的commit_id所指的提交节点就是新的基准点。该基准点之后的提交都会被git新创建的,内容一样的新提交所覆盖。rebase指令之后会详细介绍。


「edit参数」

该参数也可以达到上述效果,只不过稍微多了几个步骤。这个参数的意思是:停下rebase进程,编辑添加了该参数的提交,编辑完之后,通过调用git rebase --continue继续进行rebase;具体如下:

将添加了错误提交信息的提交的pick参数改为edit参数:
Git应用详解第二讲:Git删除、修改、撤销操作

通过:wq保存并退出:
Git应用详解第二讲:Git删除、修改、撤销操作_第33张图片

可以看到,edit参数将rebase操作停了下来。根据提示,可以通过:

git commit --amend
进入vim编辑器,修改当前提交的注释信息:
Git应用详解第二讲:Git删除、修改、撤销操作

修改完后,通过:wq保存并退出vim编辑器。再调用:

git rebase --continue
继续进行rebase操作,由此完成错误提交信息的修改:
Git应用详解第二讲:Git删除、修改、撤销操作_第34张图片

此时查看test分支的提交历史,会发现错误的提交信息得到了更正,并且与上reword参数一样,创建了新的提交,对原有提交进行了覆盖,同样内容也不发生变化:
Git应用详解第二讲:Git删除、修改、撤销操作_第35张图片

git rebase -i HEAD~n
通过上述指令也可以进入rebase交互模式,其中n表示需要显示的最近n次提交记录。比如通过以下指令,显示test分支最近的三次提交记录:

git rebase -i HEAD~3
Git应用详解第二讲:Git删除、修改、撤销操作_第36张图片
image-20200409224856810
进入rebase的交互界面之后,后续的操作和结果都与第一种方法一样,这里就不再赘述了。

六、获取帮助
1.git help config
该命令会打开git安装目录下的git-config帮助文档:
Git应用详解第二讲:Git删除、修改、撤销操作_第37张图片

image-20200412143709617
文档中详细地显示了相关操作指令的使用:

Git应用详解第二讲:Git删除、修改、撤销操作_第38张图片
image-20200412143856397
2.git config --help
效果与上述一样,都是弹出同样的帮助网页;

3.man git-config
man为linux中自带的帮助文档,也可以查看帮助;

4.git
直接在命令窗口显示常用的指令:
Git应用详解第二讲:Git删除、修改、撤销操作_第39张图片

image-20200310181313462