15

Git应用详解第二讲:Git删除、修改、撤销操作

 4 years ago
source link: http://www.cnblogs.com/AhuntSun-blog/p/12685415.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

前情提要: Git应用详解第一讲:Git分区,配置与日志

在第一讲中我们对 Git 进行了简单的入门介绍,相信聪明的你已经了解 Git 的基本使用了。

77j6RrF.png!web

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

一、删除文件

1. git rm <file>

该命令用于删除版本库中的文件;删除工作区和暂存区中的文件都会报错:

  • 若用该指令删除 工作区 中的文件,会报找不到文件的错误:

Mv26jyN.png!web

  • 若用该指令删除 暂存区 中的文件,报如下错误:

b6bY3yU.png!web

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

git rm 完成了两步操作:

  • 第一步: 将版本库中的文件删除;
  • 第二步: 将删除操作纳入暂存区( stage )。如下图所示,相当于执行了 git add test.txt ,随后可直接提交,完成 test.txt 的删除;

b6B77jZ.png!web

2. rm <file>

该命令用于删除工作区和版本库中的文件,不能删除暂存区文件;

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

  • 删除 工作区 中的文件时:

nmEnMfm.png!web

  • 删除 版本库 中的文件时:

fYremqF.png!web

git rm 不同的是 ,该指令不会将删除操作纳入 暂存区 。需要先将删除的 test.txt 纳入 暂存区 ,再提交到 版本库 才能完成 test.txt 文件的删除;

  • 删除 暂存区 中文件时:

iieyIfv.png!web

从图中可知 rm 命令只能删除工作区中的 test3.txt ,不能删除暂存区中的 test3.txt ;:

二、重命名文件

1. git mv <file1> <file2>

使用 git 命令 git mv

git mv test.txt test3.txt

​ 将 test.txt 重命名为 test3.txtmv 命令可理解为 剪切 的同时进行 更名

RV7fMbn.png!web

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

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

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

  • 第一步: 将文件 test.txt 重命名为 test3.txt
  • 第二步: 将重命名操作 test.txt -> test3.txt 纳入 暂存区

2. mv <file1> <file2>

使用系统命令 mv

mv test2.txt test3.txt

执行该语句后查看状态 git status

RfER7nr.png!web

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

  • 删除文件 test2.txt

  • 新建文件 text3.txt

再使用 git add test2.txt test3.txt 将操作提交到暂存区,通过 git status 查看状态:

QBbium7.png!web

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

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

  • 第一步: 删除工作区中重命名前的文件 test2.txt
  • 第二步: 在工作区中创建重命名后的文件 test3.txt
  • 第三步: 将上述的两个操作提交到 暂存区 中;

git mvmv 的区别相当于 git rmrm 之间的区别。

三、比较文件

1.本地文件 <-> 本地文件

diff file_a file_b

这是系统提供的比较命令,用于比较本地文件或已经提交到版本库的文件。创建文件 a 和文件 b ,使用上述指令进行比较:

ZjINBbN.png!web

diff -u a b 的输出信息中:

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

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

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

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

  • 同理: +1,3 表示: 目标文件 b 中的 1~3

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

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

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

a1
a2

并加上:

b1
b2

就能变为目标文件 b

2.工作区 <- 暂存区

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

git diff

首先,新建文件 A.txtB.txt ,修改其内容并提交到 暂存区

UFNJfu2.png!web

然后,在 工作区 中再次修改文件 A.txtB.txt 的内容:

EV7nMvJ.png!web

此时使用 git diff 进行比较:

UnyQFbv.png!web

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.txtB.txt 进行比较。

3.工作区 <- 版本库

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

git diff commit_id

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

git diff HEAD

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

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

如下图所示,先初始化 test.txt 为: 版本库中的修改 ,然后进行一次提交;随后在工作区中为 test.txt 添加 工作区的修改 ;然后执行上述比较指令,从显示出来的比较结果可知,工作区中的 test.txt 文件比最新一次提交的 test.txt 文件多了一行 工作区中的修改 内容。

Jzeieae.png!web

4.暂存区 <- 版本库

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

git diff --cached commit_id

用于比较指定提交上的 A 文件和暂存区中的 A 文件;

git diff --cached

用于比较最新提交上的 A 文件和暂存区中的 A 文件。示例如下:

ZVbENvn.png!web

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

5.总结

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

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

    指令 作用 原始文件 目标文件 diff <file1> <file2> 比较两个本地文件 本地文件/版本库 本地文件/版本库 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 <file>

如下图所示,通过 git rm 删除了版本库中的 test3.txt 文件,并将该操作提交到了暂存区。随后通过以上命令,将这一删除操作恢复到了工作区;

E3U7buZ.png!web

法二: git restore --stage <file>

这里的参数 --stage 写成 --staged 效果是一样的,作用与法一相同:

fiIbYbj.png!web

2.撤销工作区操作

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

法一: git restore <file>

如下图所示,在工作区中删除了 test3.txt 文件。然后,通过上述指令撤销了工作区中对 test3.txt 的删除操作:

EB77zae.png!web

法二: git checkout -- <file>

作用与法一相同:

NJba2qR.png!web

五、修改提交注释与作者

1.修改最近一次提交信息

git commit --amend -m '修正信息'

如果写错了提交消息:

yae2yeN.png!web

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

Az63Er6.png!web

git commit --amend

当需要为最近一次提交添加大量注释时,可以直接使用该指令进入 vim 编辑器编辑:

6bAfMrJ.png!web

mqUb2e7.png!web

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

git commit --amend --author 'Name<email>'

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

UJfMfiA.png!web

修改前该分支上最近两次的提交信息为:

J3M36vB.png!web

修改后的最近两次提交信息为:

Zz67Fr2.png!web

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

注意:修改提交注释的同时,虽然提交的内容相同,但是提交前后的 commit_id 是不同的,说明创建了一个新提交替换了原来需要修正的提交。如下图中的提交 5 与提交 3 所示:

bMjyuaA.png!web

2.修改特定提交信息

如图所示,在 test 分支进行了四次提交。现在我们想要修改第三次提交的提交信息:

rMv2IvU.png!web

git rebase -i commit_id

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

git rebase -i 678e0

773AZr7.png!web

在这个界面中,我们可以通过将 pick 参数修改为其他 rebase 提供的参数,从而对第三次错误提交进行修改。有两个参数可以实现这一目的:

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

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

reword 参数

该参数的意思是:直接修改设置了该参数的提交的提交注释。这里应该将第三次提交的 pick 参数改为 reword

j6n6bqU.png!web

通过 :wq 保存并退出,随后再次进入 vim 编辑器,这次是修改设置了 reword 参数的提交的提交注释:

UnMRvqb.png!web

将它改为正确的提交信息:

AFJ7Bbi.png!web

通过 :wq 保存并退出 vim 编辑器,完成错误提交信息的修改,再次查看历史提交信息:

6VjeemB.png!web

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

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

edit 参数

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

将添加了错误提交信息的提交的 pick 参数改为 edit 参数:

3QJFRzy.png!web

通过 :wq 保存并退出:

eQBfmy6.png!web

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

git commit --amend

进入 vim 编辑器,修改当前提交的注释信息:

eyqAVzi.png!web

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

git rebase --continue

继续进行 rebase 操作,由此完成错误提交信息的修改:

EBJjE3i.png!web

此时查看 test 分支的提交历史,会发现错误的提交信息得到了更正,并且与上 reword 参数一样,创建了新的提交,对原有提交进行了覆盖,同样内容也不发生变化:

eIzIFfi.png!web

git rebase -i HEAD~n

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

git rebase -i HEAD~3

ABNr2ia.png!web

进入 rebase 的交互界面之后,后续的操作和结果都与第一种方法一样,这里就不再赘述了。

六、获取帮助

1. git help config

该命令会打开 git 安装目录下的 git-config 帮助文档:

vqmyAbn.png!web

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

JBR7r2j.png!web

2. git config --help

效果与上述一样,都是弹出同样的帮助网页;

3. man git-config

manlinux 中自带的帮助文档,也可以查看帮助;

4. git

直接在命令窗口显示常用的指令:

3aiqUzB.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK