前言

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

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

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

一、删除文件

1.git rm <file>

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

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

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

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

git rm完成了两步操作:

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

2.rm <file>

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

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

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

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

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

  • 删除暂存区中文件时:

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

二、重命名文件

1.git mv <file1> <file2>

使用git命令git mv

git mv test.txt test3.txt

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

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

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

  • 删除文件test2.txt

  • 新建文件text3.txt

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

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

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

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

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

三、比较文件

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

diff file_a file_b

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

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

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

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

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

  • -1,3- 表示原文件即a1 表示原文件中的第一行,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,修改其内容并提交到暂存区

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

此时使用git diff进行比较:

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文件多了一行工作区中的修改内容。

4.暂存区 <- 版本库

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

git diff --cached commit_id

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

git diff --cached

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

可以看到,暂存区中的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文件,并将该操作提交到了暂存区。随后通过以上命令,将这一删除操作恢复到了工作区;

法二:git restore --stage <file>

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

2.撤销工作区操作

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

法一:git restore <file>

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

法二:git checkout -- <file>

作用与法一相同:

五、修改提交注释与作者

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

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

如果写错了提交消息:

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

git commit --amend

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

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

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

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

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

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

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

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

2.修改特定提交信息

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

git rebase -i commit_id

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

git rebase -i 678e0

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

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

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

reword参数

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

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

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

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

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

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

edit参数

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

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

通过:wq保存并退出:

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

git commit --amend

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

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

git rebase --continue

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

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

git rebase -i HEAD~n

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

git rebase -i HEAD~3

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

六、获取帮助

1.git help config

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

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

2.git config --help

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

3.man git-config

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

4.git

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

Git应用详解第二讲:Git删除、修改、撤销操作的更多相关文章

  1. PE文件格式详解,第二讲,NT头文件格式,以及文件头格式

    PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...

  2. Git应用详解第九讲:Git cherry-pick与Git rebase

    前言 前情提要:Git应用详解第八讲:Git标签.别名与Git gc 这一节主要介绍git cherry-pick与git rebase的原理及使用. 一.Git cherry-pick Git ch ...

  3. git 使用详解(6)—— 3种撤消操作

    接下来,我们会介绍一些基本的撤消操作相关的命令.请注意,有些操作并不总是可以撤消的,所以请务必谨慎小心,一旦失误,就有可能丢失部分工作成果. 修改最后一次提交 git commit --amend 有 ...

  4. Android学习之基础知识十三 — 四大组件之服务详解第二讲(完整版的下载示例)

    上一讲学习了很多关于服务的使用技巧,但是当在真正的项目里需要用到服务的时候,可能还会有一些棘手的问题让你不知所措.接下来就来综合运用一下,尝试实现一下在服务中经常会使用到的功能——下载. 在这一讲我们 ...

  5. Git应用详解第三讲:本地分支的重要操作

    前言 前情提要:Git应用详解第二讲:Git删除.修改.撤销操作 分支是git最核心的操作之一,了解分支的基本操作能够大大提高项目开发的效率.这一讲就来介绍一些分支的常见操作及其基本原理. 一.分支概 ...

  6. Git应用详解第十讲:Git子库:submodule与subtree.md

    前言 前情提要:Git应用详解第九讲:Git cherry-pick与Git rebase 一个中大型项目往往会依赖几个模块,git提供了子库的概念.可以将这些子模块存放在不同的仓库中,通过submo ...

  7. Git初探--笔记整理和Git命令详解

    几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...

  8. Git应用详解第六讲:Git协作与Git pull常见问题

    前言 前情提要:Git应用详解第五讲:远程仓库Github与Git图形化界面 git除了可以很好地管理个人项目外,最大的一个用处就是实现团队协作开发.况且,linus大神开发git的初衷就是为了维护L ...

  9. Git应用详解第七讲:Git refspec与远程分支的重要操作

    前言 前情提要:Git应用详解第六讲:Git协作与Git pull常见问题 这一节来介绍本地仓库与远程仓库的分支映射关系:git refspec.彻底弄清楚本地仓库到底是如何与远程仓库进行联系的. 一 ...

随机推荐

  1. 一文详解Hexo+Github小白建站

    作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...

  2. SpringBoot WebSocket STOMP 广播配置

    目录 1. 前言 2. STOMP协议 3. SpringBoot WebSocket集成 3.1 导入websocket包 3.2 配置WebSocket 3.3 对外暴露接口 4. 前端对接测试 ...

  3. Drf 序列化 ModelSerializer跨表取数据

    1.对于OneToOne.Foreignkey.choices字段可以使用source取出相关信息: class CourseSerializer(serializers.ModelSerialize ...

  4. (转)伪指令LTORG和LTONG浅析

    原文地址:http://zqwt.012.blog.163.com/blog/static/1204468420103196564/ 定义和作用 LTORG或LTONG用于声明一个数据缓冲池(也称为文 ...

  5. css hover 动画 transition:background-color 0.2s,color 0.2s; 外层套内层,正常是 里外层 鼠标上来 外层有hover,如果就想到里层hover触发外层hover,要用外层position 定义绝对定位,内层的hover跳出外层的div,这样视觉上就是两个单独的div,进行内外层联动。

    css hover 动画 transition:background-color 0.2s,color 0.2s; 外层套内层,正常是 里外层 鼠标上来 外层有hover,如果就想到里层hover触发 ...

  6. Linux---使用kill杀不掉进程解决方案

    今天打开Linux虚拟机,然后使用jps命令查看,莫名奇妙多了一个1889进程 然后使用kill杀掉后,再运行jps还是存在此进程.于是乎开始大量百度,最终找到了解决方案. 说的很清楚了,杀不掉的原因 ...

  7. snmap弱口令攻击利用

    科普Snmap: 简单网络管理协议(SNMP) 是专门设计用于在 IP 网络管理网络节点(服务器.工作站.路由器.交换机及HUBS等)的一种标准协议,它是一种应用层协议.具体废话就不多说了,自己百度去 ...

  8. Python编写“求一元二次方程的解”

    #求一元二次方程的解 import math def equation(a,b,c): h=b*b-4*a*c #一元二次方程的解,百度来的 if h>=0: x1=(-b+math.sqrt( ...

  9. JDBC怎么连接数据库

    1:注册驱动:class.forName("com.mysql.jdbc.Driver"); 2:连接数据库:DriverManager.getConnection(url , u ...

  10. Django-jwt token生成源码分析

    一. 认证的发展历程简介 这里真的很简单的提一下认证的发展历程.以前大都是采用cookie.session的形式来进行客户端的认证,带来的结果就是在数据库上大量存储session导致数据库压力增大,大 ...