• Git版本控制管理——diff


    Git中的diff命令可以显示文件之间的差异,同时-r选项可以遍历两个树对象,同时显示它们的差异。

    从Git中的对象类型上看,一个树对象值只代表版本库中的一个目录层级,它包含该目录下的直接文件和它的所有直接子目录的信息,但不包括所有子目录的完整内容。而树对象引用所有子目录的树对象,所以对应项目根目录的树对象实际上代表某个时刻的整个项目,因此也可以说,git diff遍历两棵树。

    git diff命令格式

    存在三个可供树或类树对象使用git diff命令的基本来源:

    • 整个提交图中的任意树对象
    • 工作目录
    • 索引

    通常情况下,git diff命令进行树的比较时可以通过提交名,分支名或标签名,同时,工作目录的文件和目录结构还有在索引中暂存文件的完整结构,都可以被看为树。

    而git diff命令就可以使用上述三种来源的组合来进行如下4中基本比较:

    • git diff:比较工作目录和索引间的差异
    • git diff commit:比较工作目录和给定提交间的差异,常见的用法是HEAD
    • git diff --cached commit:比较索引中的变更和给定提交的变更的差异,如果省略commit,则默认为HEAD
    • git diff commit1 commit2:比较两个提交之间的差异,该比较会忽略工作目录和索引

    命令行的参数个数决定使用哪种基本形式和比较什么。可以比较任意两个提交或树,比较的两个对象不需要有直接的或间接的父子关系。如果省略了一个或两个参数,那么git diff命令会比较默认的对象,比如工作目录,索引,HEAD等。

    除了这几种基本形式的git diff命令外,还有一些比较有用的选项:

    • --M:该选项可以用来查找重命名并且生成一个简化的输出,只简单地记录文件重命名,如果文件不是纯的重命名,同时还有内容上的更改,那么Git会将它们调出
    • -w或--ignore-all-space:这两个选项会在比较时忽略空白字符
    • --stat:这个选项会显示针对两个树状态之间差异的统计数据,报告用简洁的语法显示有多少行发生了改变,有多少行添加了,有多少行删除了
    • --color:该选项会使输出结果使用多种颜色显示,一种颜色显示diff中的一种变化

    git diff例子

    首先在空目录下初始化版本库:

    1. git init
    2. echo abc > file1
    3. git add file1
    4. git commit -m "commit file1"
    5. echo abcd > file2
    6. git add file2
    7. git commit -m "commit file2"

    然后执行:

    1. $ echo 1111 > file1
    2. $ git diff
    3. warning: LF will be replaced by CRLF in file1.
    4. The file will have its original line endings in your working directory
    5. diff --git a/file1 b/file1
    6. index 8baef1b..5f2f16b 100644
    7. --- a/file1
    8. +++ b/file1
    9. @@ -1 +1 @@
    10. -abc
    11. +1111

    文件file1在工作目录中已经修改,但是并没有暂存,因此可以直接使用git diff进行比较,此时比较的就是工作目录和索引的差异。

    如果想要将工作目录与索引或版本库进行比较:

    1. $ git diff --cached
    2. $ git diff HEAD
    3. warning: LF will be replaced by CRLF in file1.
    4. The file will have its original line endings in your working directory
    5. diff --git a/file1 b/file1
    6. index 8baef1b..5f2f16b 100644
    7. --- a/file1
    8. +++ b/file1
    9. @@ -1 +1 @@
    10. -abc
    11. +1111

    可以看出,索引和版本库是没有差异的,而工作目录和版本库是存在差异的,这里的差异打印和之前使用git diff的打印是相同的。

    1. $ git add file1
    2. warning: LF will be replaced by CRLF in file1.
    3. The file will have its original line endings in your working directory
    4. $ echo 2222 > file1

    此时再进行比较:

    1. $ git diff
    2. warning: LF will be replaced by CRLF in file1.
    3. The file will have its original line endings in your working directory
    4. diff --git a/file1 b/file1
    5. index 5f2f16b..c7dc989 100644
    6. --- a/file1
    7. +++ b/file1
    8. @@ -1 +1 @@
    9. -1111
    10. +2222
    11. $ git diff HEAD
    12. warning: LF will be replaced by CRLF in file1.
    13. The file will have its original line endings in your working directory
    14. diff --git a/file1 b/file1
    15. index 8baef1b..c7dc989 100644
    16. --- a/file1
    17. +++ b/file1
    18. @@ -1 +1 @@
    19. -abc
    20. +2222
    21. $ git diff --cached
    22. diff --git a/file1 b/file1
    23. index 8baef1b..5f2f16b 100644
    24. --- a/file1
    25. +++ b/file1
    26. @@ -1 +1 @@
    27. -abc
    28. +1111

    这里将file1暂存,同时在工作目录修改了file1的内容,这里的工作目录,索引,版本库的内容彼此之间都是不同的,因此会有上面的比较。

    这里将file1提交:

    1. $ git commit file1 -m "commit file1 again"
    2. warning: LF will be replaced by CRLF in file1.
    3. The file will have its original line endings in your working directory
    4. warning: LF will be replaced by CRLF in file1.
    5. The file will have its original line endings in your working directory
    6. [master 3fc324d] commit file1 again
    7. 1 file changed, 1 insertion(+), 1 deletion(-)
    8. $ git status
    9. On branch master
    10. nothing to commit, working tree clean
    11. $ cat file1
    12. 2222
    13. $ git diff HEAD HEAD^1
    14. diff --git a/file1 b/file1
    15. index c7dc989..8baef1b 100644
    16. --- a/file1
    17. +++ b/file1
    18. @@ -1 +1 @@
    19. -2222
    20. +abc

    这里可以看出,提交之后HEAD和HEAD^存在差异。

    git diff和提交范围

    git命令支持两个点..来显示两个提交之间的差异,即以下两条命令是等同的:

    1. git diff commit1..commit2
    2. git diff commit1 commit2

    而在git log命令中,两点..是用来显示整个提交范围内的历史记录的,这是两者的差异之处。也可以看出:

    • git diff不关心比较的文件的历史,也不关心分支,即文件内容的差异
    • git log关心的则是文件的变动历史,即文件修改的历史

    路径限制的git diff

    通常情况下,git diff会基于从给定树对象的根开始的整个目录结构。然而,可以使用和git log中相同的路径限制来限制git diff只输出版本库的一个子集。

    1. $ echo 1111 > file1
    2. $ echo 2222 > file2
    3. $ git diff
    4. warning: LF will be replaced by CRLF in file1.
    5. The file will have its original line endings in your working directory
    6. warning: LF will be replaced by CRLF in file2.
    7. The file will have its original line endings in your working directory
    8. diff --git a/file1 b/file1
    9. index 8baef1b..5f2f16b 100644
    10. --- a/file1
    11. +++ b/file1
    12. @@ -1 +1 @@
    13. -abc
    14. +1111
    15. diff --git a/file2 b/file2
    16. index acbe86c..c7dc989 100644
    17. --- a/file2
    18. +++ b/file2
    19. @@ -1 +1 @@
    20. -abcd
    21. +2222
    22. $ git diff file1
    23. warning: LF will be replaced by CRLF in file1.
    24. The file will have its original line endings in your working directory
    25. diff --git a/file1 b/file1
    26. index 8baef1b..5f2f16b 100644
    27. --- a/file1
    28. +++ b/file1
    29. @@ -1 +1 @@
    30. -abc
    31. +1111

    比如上面的例子,如果同时修改了file1,file2,而在当前状态下只需要考虑file1的提交,那么就可以使用git diff file1来限制比较的对象只为file1。

  • 相关阅读:
    AI绘画的崛起与多平台对比
    大厂技术面试中的手撕代码应该如何准备?
    Centos7配置国内yum源
    使用require.context实现优雅的预加载
    Git使用
    港联证券:“火箭蛋”来袭 蛋价涨势能否延续?
    手写杨辉三角
    GaussDB T分布式集群安装部署
    2022十三届蓝桥杯国赛题解
    大腿神经网络解剖图片,大腿神经网络解剖图谱
  • 原文地址:https://blog.csdn.net/SAKURASANN/article/details/125472567