书接上回,直入主题!如果你是接着上篇来的,那么先运行git reset HEAD test.txtgit checkout test.txt来放弃当前的更改,使最新的commit回到“commit temp”,这个时候运行git status,会看到“nothing to commit, working directory clean”。这里,“nothing to commit”说明暂存目录是空的,“working directory clean”说明你的工作目录也没有任何修改。

回到这种状态是为了方便我们下面的讲解,此时的SourceTree状态为:

diff - 来,叔叔给你检查身体

好好的一个diff命令能让我想到的就是这句猥琐的经典台词了,diff可以让你比较项目中任意两个状态的差别。说到比较,自然就又有source和target了,那么diff命令最直观的用法其实就是git diff source target。这里的source和target与checkout中的类似,可以是“commit的hash”,“分支名”,“快捷方式”。比如,我们想比较图13中前两个commit,运行git diff ce81811 6382c7d即可,得到的结果如下图:

可以看到,比较的结果其实是以target为基准的,也就是说target相比于source有了哪些变化,图15的结果中commit “6382c7d”比“ce81811”少了三行,多了一行,分别用减号和加号来表示。同样,使用git diff master branch2git diff HEAD branch2得到的结果与上面是一致的,分支名和“HEAD”一类的都可以看做是commit的快捷方式。

这种source和target都给的情况是最容易理解的,复杂就复杂在如果我们省略一个参数会怎么样呢?比如运行git diff branch2结果如下图所示:

可以看到,图16的结果与图15是相反的。也就是说git diff branch2git diff branch2 HEAD的结果是一样的,即如果只给一个参数,则这个参数为source,target默认为当前所在分支的最新的commit。现在就下这个结论对吗?注意我们现在处在“暂存目录为空”+“工作目录clean”的状况下,现在我们把工作目录搞成dirty试试,给test.txt再加一行“test 6”并保存。这时再试试git diff branch2,结果如图17所示:

可以看到新建的“test 6”也进去了。可以断定,在工作目录不clean的情况下,target默认表示的是工作目录。这个结论是否还是为时尚早呢,如果暂存目录有东西会怎么样?运行git add test.txt,然后继续git diff branch2,发现结果与图17是一致的,这还是不能说明问题,因为此时工作目录与暂存目录是一致的(都到test 6)。那么我们再加一行“test 7”,这时工作目录为“test 7”,暂存目录还是“test 6”,此时运行git diff branch2,发现“test 7”这一行也被加了进去。这个时候我们基本可以断定,target默认显示的确实是工作目录。

前面看了省略一个参数的情况,那俩参数都省略会咋样呢?运行git diff结果如下图:

可以看到比较结果为只增加了“test 7”,所以这个时候的source是暂存目录,而target还是工作目录。为了验证这个推测,我们运行git add test.txt,将“test 7”的修改也add到暂存目录,这时运行git diff,返回结果为空,因为此时暂存目录和工作目录是一致。我们做一次提交git commit -m "commit 6,7",这时,暂存目录为空,工作目录clean,继续运行git diff,还是空的。到这里我们可以断定,如果两个参数都省略,那么默认source为暂存目录,默认target为工作目录。

前面的情况涉及到“各个commit之间的比较”,“各个commit与工作目录的比较”,“暂存目录与工作目录的比较”,那么只差一种情况了,我想比较“暂存目录”和“各个commit”怎么整呢?为了实现这个,我们先给暂存目录来点东西:加一行“test 8”并保存,然后git add test.txt,然后在编辑test.txt加一行“test 9”,这么做的原因是让暂存区有东西而且暂存区与工作目录不同。这时运行git diff --cached branch2,可以发现结果为下图:

从图中可以发现“test 8”在而“test 9”不在,说明此时的target已经变成暂存区了。

总结一下diff的各种情况:

  1. git diff source target返回的结果是target相对于source的变化,这里的source和target可以是commit的hash/分支名/快捷方式
  2. 如果只给一个参数,则这个参数就是source,而默认的target是工作目录,如果工作目录clean的话,则target为当前所在分支的最新commit
  3. 如果一个参数都不给,默认的source是暂存目录,而target还是工作目录
  4. 如果想要使暂存目录作为target的话,需要使用--cached参数

在继续往下走之前,先将刚才的更改全部提交,运行git add test.txtgit commit -m "commit 8,9"

reset - 有了我你随便咋折腾都行

版本控制最大的好处就是可以方便的找到以前的版本并恢复,所以从这个角度来说reset命令的地位还是比较重要的,可以让你无所顾忌的随便蹂躏整个项目。说到恢复,也有source和target的概念,这里的source肯定就是各个commit(包含分支名和快捷方式),而target根据不同的参数可能是暂存目录或工作目录或两者同时都是target。比如我们选定当前commit的父commit作为source,运行git reset HEAD~ test.txt,提示有Unstaged change,此时SourceTree里的Uncommitted changes的状态如下图:

从图20中可以发现,暂存区域的文件状态与父commit时一致,而改变是减掉了“test 8”和“test 9”两行,说明工作目录并没有发生变化(工作目录含有这两行)。可以看到这种情况下的target其实是暂存目录,它并没有改变工作目录。说到这里,把前面欠的课补上,还记得前面我们做git add的反操作时用了git reset HEAD test.txt,其实也是将HEAD状态的文件恢复到了暂存区,工作目录保持不变,而那时最新commit的文件状态和工作目录是一致的,所以最终产生的效果就是“git add反操作”。其实这里的HEAD也可以省略,因为默认的source就是当前所在分支的最新commit。更进一步,文件名test.txt也可以省略,默认会将Repo里的所有文件恢复,因为此时我们就只有这一个文件,所以效果是一样的。

再介绍reset的其他参数之前,我们想把刚才的reset再给reset掉,很简单,只要再运行一遍git reset即可,因为我们需要的其实是“git add的反操作”。然后加参数运行reset,git reset --soft HEAD~,注意这里我们并不是省略文件名,而是一旦加了--soft就不能跟文件路径,而是恢复整个项目的所有文件了,结果如下图所示:

可以看到,这次reset直接改变了HEAD,原先的“commit 8,9”消失了,最新的commit变成了原先的HEAD~,但这次reset仍然没有修改工作目录,只是将“commit 8,9”的文件状态add到了暂存区。既然有--soft参数,那肯定会有--hard参数,这次我们保持当前的状态,直接运行git reset --hard ce81811(commit temp所对应的hash),发现当前最新的commit变成“commit temp”,并且暂存区域是空的,然后工作目录也是clean的,说明--hard参数不管运行命令前处于什么状态,都直接将工作目录恢复到“commit temp”的状态,清空暂存区域。这也比较符合--hard这个单词强硬的意思。此时的SourceTree状态图为:

从图中可以看出,“commit temp”之前的commit都已经丢失了,整个项目被强制恢复到了“commit temp”所在的状态。

总结一下reset的用法:

  1. git reset [commit hash/分支名/快捷方式] [文件名]类似“git add的反操作”,直接将所在commit的文件状态恢复到暂存区域。省略commit则默认为HEAD,省略文件名默认为所有文件。只改变暂存目录,不改变工作目录,当前commit不变。
  2. git reset --soft [commit hash/分支名/快捷方式]软恢复,将恢复前所在commit的文件状态恢复到暂存区,当前最新commit为参数中的commit。只改变暂存目录,不改变工作目录,当前commit改变。
  3. git reset --hard [commit hash/分支名/快捷方式]硬恢复,强制将整个项目恢复为参数中的commit时的文件状态,清空暂存目录,工作目录clean。暂存目录和工作目录同时被改变,当前commit改变。

关于reset命令的其他补充:当前HEAD已经位于“commit temp”,是不是前面的commit都找不回来了?当然不会,reset过的操作也是可以被reset的。有两种方法:

  • 如果记得“commit 8,9”的hash(从图20中可以看到),则直接git reset --hard 1a222c3,则项目直接强制恢复到“commit 8,9”所在的状态。
  • 如果不记得的话,运行git reflog,这个命令会输出一个列表,包含HEAD发生的所有变化。如下图:

在图23中可以发现“commit 8,9”所对应的条目为1a222c3 HEAD@{9}: commit: commit 8,9,第一项就是commit hash,第二项自然是快捷方式了。那么只要我们运行git reset --hard HEAD@{9}即可。注意,我的reflog输出结果可能与你的不同,因为写教程的需要我可能做了很多额外的操作。

P.S. 显然两篇也不够啊,发现主要是Retina屏的截图太尼玛大了。。。下篇再讲剩下的吧!

from: http://pinkyjie.com/2014/08/09/git-notes-part-2/

Git笔记(二)——[diff, reset]相关推荐

  1. 【Git学习笔记二】时光穿梭机

    版权声明:本文为 小异常 原创文章,非商用自由转载-保持署名-注明出处,谢谢! 本文网址:https://blog.csdn.net/sun8112133/article/details/103888 ...

  2. 【Git笔记2】必知习惯和如何版本回退

    良好的习惯会让工作和生活如鱼得水,在使用git的时候有些必知习惯和概念你要get一下,总有些许失误,如:已经提交了不合适的修改到版本库时还没有把自己的本地版本库推送到远程,想要撤销本次提交,或者已经p ...

  3. 【Git笔记3】关于撤销、删除、恢复的那些事儿

    在跻身于"国庆抢票大战"的我们,不要忘记学习,今天接着上篇 [Git笔记2]必知习惯和如何版本回退,继续开干!一起来瞅瞅如何撤销没有add的修改,如何撤销以及add到暂存区的修改, ...

  4. Git笔记(ydl)

    Git笔记(ydl) 第一章 理论基础 一 .Git安装 windows安装:进入网站https://git-scm.com/下载安装,然后在cmd命令行配置 直接去腾讯软件中心下载也可以! > ...

  5. git 32位_完整的GIT笔记 快速上手小白教程

    GIT 是什么? Git 是目前世界上最先进的分布式版本控制系统.并且它是一个免费的.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. 什么是版本控制系统 版本控制是一种系统,它跟踪一 ...

  6. Git笔记(33) Rerere

    Git笔记(33) Rerere 1. 重用记录的解决方案 2. 干净的合并和变基 3. 举例 1. 重用记录的解决方案 git rerere 功能是一个隐藏的功能 正如它的名字"重用记录的 ...

  7. Git笔记(32) 高级合并

    Git笔记(32) 高级合并 1. 合并冲突 1.1. 中断一次合并 1.2. 忽略空白 1.3. 手动文件再合并 1.4. 检出冲突 1.5. 合并日志 1.6. 组合式差异格式 2. 撤消合并 2 ...

  8. Git笔记(27) 储藏与清理

    Git笔记(27) 储藏与清理 1. 混乱的状态 2. 储藏工作 3. 创造性的储藏 4. 从储藏创建一个分支 5. 清理工作目录 1. 混乱的状态 有时,当在项目的一部分上已经工作一段时间后,所有东 ...

  9. Git笔记(23) 不同角色的贡献

    Git笔记(23) 不同角色的贡献 1. 私有小型团队 2. 私有管理团队 3. 派生的公开项目 4. 通过邮件的公开项目 1. 私有小型团队 可能会遇到的最简单的配置是有一两个开发者的私有(闭源)项 ...

最新文章

  1. python库整理:networkx 包
  2. android单片机蓝牙小车,手把手教你做蓝牙小车
  3. java 怎么比较两个日期_如何在Java中比较两个日期?
  4. CSS Margin(外边距)
  5. jtextpane设置不能选中_你会设置数据有效性吗?
  6. 【笔记】双线性池化(Bilinear Pooling)详解、改进及应用
  7. 产品读书《大数据时代:生活、工作与思维的大变革》
  8. 安卓 文本框怎么贴近边缘_【安卓,iOS】全网最火的充电提示音教程来啦
  9. vue 中 vue-print-nb 表格打印不全的问题
  10. Cygwin的安装及csh的配置和使用(批量下载FNL数据方法)
  11. linux dpkg: 错误: 无法打开软件包的 info 文件 /var/lib/dpkg/available 以便读取: 没有那个文件或目录
  12. spring中 shiro logout 配置方式
  13. mysql创建数据库并创建表
  14. 文本(文章内容)编辑器(CMS管理)
  15. C语言小游戏第二弹~1-100猜数字(无聊时候摸鱼必备)
  16. ubuntu安装RoboWare Studio及其遇到错误解决
  17. 学python还是c加加更实用_c语言和python先学哪个比较简单
  18. 今日公益明星排行榜--百度搜索风云榜
  19. mac升级到 macos ventura 13.0 后,git失效及gitlab认证失败问题
  20. 计算机评游戏图形低,高手分享:快速辨别图形分数与游戏图形之差

热门文章

  1. Linux定时增量更新文件--转
  2. 从weblogic的一个教训
  3. 中国程序员如何升职加薪,也许我们该学学印度人
  4. 今日头条|张一鸣:我遇到的优秀年轻人的5个特质
  5. 沪港通:利好出尽就是利空
  6. 每日一博 - Review线程池
  7. 设计模式 - 基本功的重要性
  8. MyBatis-08MyBatis注解方式之@Insert
  9. Translucent System Bars-4.4新特性
  10. 2021佛山市地区高考成绩排名查询,佛山市高中排名分数线,佛山高中排名2021最新排名...