Git实用教程 5.1:版本对比2
这一讲教给大家一个灰常重要的命令,看我真诚的小眼神 ()
status 命令虽然可以查看到当前的工作状态,也有 Git 给你提供友情提示,但它只会告诉你版本发生了改变(哪个文件有变化,增加、减少了多少行),但它没法告诉你版本之间到底有哪些不同。而我们缺的,正正就是这个功能!!
今天我们要讲的命令叫 diff,就是 different 的缩写,这个命令是专门用来找茬的。
为了让大家学得实打实,这里决定重新建立一个项目,大家 Follow me!
准备工作
(这一步都是前面的内容,不记得的自己回去看看复习)
•Step One:
–创建一个叫做MyProject2的新文件夹作为本次演示的项目,初始化Git
•Step Two:
–现在模拟我们在完成《零基础入门学习Python》的一道课后作业题。
–创建一个game.py的文件,按要求写上代码。
–再创建一个README.md文件,写清楚这是一个课后作业的项目。
•Step Three:
–执行git add README.md game.py命令将两个文件都添加到暂存区域。
–接着执行git commit -m "猜数字游戏"提交项目的第一个快照。
•Step Four:
–接着我们按照课后作业的要求改写game.py文件的代码。
–README.md文件也要改一改。
以下为核心内容:
比较暂存区域与工作目录
直接执行 git diff 命令是比较暂存区域与工作目录的文件内容:
(如果出现乱码,请看文末解决方法)
What???
不急,我一个个给你解释……
首先,diff 命令是 linux 上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方。diff 程序的输出被称为补丁 (patch),因为 Linux 系统中还有一个 patch 程序,可以根据 diff 的输出将 a.c 的文件内容更新为 b.c。
diff 现在已经是 Git 不可或缺的一部分了!值得一提的是,现在的 diff 已经可以很好的支持二进制文件了,比如 docx 文件以前不支持,现在都支持啦~\(≧▽≦)/~
第一行:diff --git a/README.md b/README.md
表示对比的是存放在暂存区域的 README.md 和工作目录的 README.md
第二行:index 7966837..472a180 100644
表示对应文件的 ID 分别是 7966837 和 472a180,左边暂存区域,后边当前目录。
最后的 100644 是指定文件的类型和权限。喏,具体的定义我也帮你找出来了(Linux 系统的定义,看不懂没关系,我知道有人需要,所以顺便贴出来):
The following flags are defined for the st_mode field:
S_IFMT 0170000 bit mask for the file type bit fields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
第三行:--- a/README.md
--- 表示该文件是旧文件(存放在暂存区域)
第四行:+++ b/README.md
+++ 表示该文件是新文件(存放在工作区域)
第五行:@@ -1 +1,2 @@
以 @@ 开头和结束,中间的“-”表示旧文件,“+”表示新文件,后边的数字表示“开始行号,显示行数”
一脸懵逼。。。
不要紧,先看接着的六、七行的内容:
这是将两个文件合并显示的结果,前边有个 + 的绿色的那一行说明是新文件独有的,浅灰色的则是两个文件所共有的内容。
所以,+1,2 表示新文件在合并显示中从第 1 行开始,显示 2 行。
那为啥 -1 后边没有显示的行数?
因为在合并显示的结果中,旧文件已经完全包含在新文件中了(也就是旧文件没有自己“独有的”内容)。
第八行:\ No newline at end of file
这是 Git 出于善意的提醒:文件不是以换行符结束。
为什么会有这样多此一举的提醒呢?
仔细推敲下你就会明白了:diff 将两个文件合并打印,到达最后一个字符的时候,无论文件中是否存在换行符,diff 都需要打印一个换行符!为啥?为了好看呗!!所以如果你的文件最后一个字符不是以换行符结尾,但 diff 又自行添加了一个换行符,所以它觉得有义务提醒你它这么做了!
TIPS:最后空一行是一个良好的编程习惯
再下边就是另外两个文件(game.py)的比较了,理解的方式跟上边一样。
两个 @@ 之间表示下方合并显示的范围,@@ -1,20 +1,28 @@ 表示旧文件从第 1 行开始,显示 20 行;新文件从第 1 行开始,显示 28 行。
不信你可以数数看:1,2,3,4,5,6
咦……
这个点点(:)是什么鬼?
意思是世界太大,窗口太小,没法全部显示,正在等待你的命令……
移动命令
这时候你可以输入下边的移动命令:
按下 j 按键表示向下移动一行,按下 k 按键则是向上移动一行。当然你也可以使用上、下方向键,但小甲鱼不建议你这么做,因为按方向键意味着你的右手需要离开主键盘区……这一来一回很消耗时间和节奏的(论 Vim or Emacs 习惯的重要性 )!
怎么?嫌移动的速度太慢?
好,试试 f 和 b 两个按键!
f 表示向下一页(一个窗口的内容);b 表示向上一页的移动。
一页又太多了?半页可否?
可以!d 表示向下移动半页;u 表示向上移动半页。
跳转命令
是否可以直接跳转到开头和结尾呢?
可以,按 g 去到第一行,按 G 去到最后一行。
不这么极端行不行?
可以,先输入数字 3,再按下 g,表示去到第 3 行。
搜索命令
比如想看下关于 print 函数的内容有没有变动,可以使用搜索命令。
输入斜杠(/)或问号(?),后边输入搜索的关键字:
按下回车,所有匹配的关键字均高亮显示:
然后斜杠(/)和问号(?)的区别主要是搜索方向的不同:斜杠(/)表示从当前位置向下搜索,问号(?)表示从当前位置向上搜索。
接着输入 n 表示顺着当前的搜索方向快速跳转到下个匹配的位置,大写的 N 则是与当前搜索方向相反。
退出和帮助
在点点(:)后边输入 q,表示退出 diff;输入 h 表示进入帮助界面,你会看到很多命令和功能(当然都是鸟文),输入 q 可以退出帮助界面。
其实习惯于 Linux 终端界面的鱼油们一定对这些并不陌生……
这些命令也好,操作也罢,都是赤裸裸的文化入侵哈(让你们用 Windows,刚开始肯定无比蛋疼,但习惯 Linux 的大牛们不知道用得多欢快)~~~
比较两个历史快照
Git 仓库中存放一个个提交的快照,我们能不能对比其中的任意两个呢?
当然可以!
我们执行 git commit -am "add feature - 3 opportunities" 命令,添加并提交工作目录中的所有文件:
执行 git log 命令,可以看到现在 Git 仓库中已经有两个快照了:
执行 git diff 64a965 af8a93 命令,即可比较 Git 仓库中两个快照的差异:
比较当前工作目录和 Git 仓库中的快照
现在我们稍微改动一下 README.md 文件的内容:
目前我们的 Git 仓库应该是酱紫:
三棵树是这样:
如果希望比较第一份快照(af8a93)和当前目录的内容,输入 git diff af8a93 命令即可:
如果希望比较最新提交的快照和当前目录的内容,输入 git diff HEAD 命令即可:
比较暂存区域和 Git 仓库快照
执行 git add README.md 命令,将第三版的 README.md 文件添加到暂存区域。
然后三棵树就是这样了:
如果希望比较最新提交的快照和暂存区域的文件,只需要执行 git diff --cached 命令:
当然也可以指定其他快照,就是需要多写上一个 ID 值:
最后,给大家奉上梳理的终极奥义图:
使用 Windows 编辑的朋友应该会遇到下边的怪事儿:
这绿色的和灰色的的乱码是什么鬼?
肿么跟演示的就不一样了?
方法1:(这是大家普遍认为的方法,应该多大部分人有效吧)
在 Windows 下,如果你看到乱码,乃是由于 Windows 的不团结导致编码问题,请使用全世界通用的 UTF-8 无 BOM 格式。
使用 Nodepad++ 打开文件,点击“格式(M)”->“转为 UTF-8 无 BOM 编码格式”:
如果上面的方法没有解决问题,跟我一样,方法一对我无效,还有方法2:
方法2:
在命令行下输入以下命令:
$ git config --global core.quotepath false # 显示 status 编码
$ git config --global gui.encoding utf-8 # 图形界面编码
$ git config --global i18n.commit.encoding utf-8 # 提交信息编码
$ git config --global i18n.logoutputencoding utf-8 # 输出 log 编码
我使用cmd,直接添加环境变量LESSCHARSET,变量值utf-8,重启电脑让变量生效。
不重启电脑快速测试的话,cmd输入命令
set LESSCHARSET=utf-8