教程 > Git 教程 > Git 仓库操作 阅读:1013

Git diff 比较更改

git diff 是一个多用途的 Git 命令,执行时会在 Git 数据源上运行 diff 函数。这些数据源可以是一次提交、一个分支或文件等。本章节将讨论常见的git diff工作流模式调用和不同的工作流模式。git diff命令通常与git statusgit log 一起使用对 Git 仓库的当前状态进行分析。

读区差异: 输出

原始输出格式

以下示例将在一个简单的 repo 中执行。使用以下命令创建仓库:

$ mkdir diff_test_repo
$ cd diff_test_repo
$ touch diff_test.txt
$ echo "this is a git diff test example" > diff_test.txt
$ git init .
Initialized empty Git repository in /Users/jiyik/workspace/diff_test_repo/.git/
$ git add diff_test.txt
$ git commit -am"add diff test file"
[main (root-commit) 6f77fc3] add diff test file
1 file changed, 1 insertion(+)
create mode 100644 diff_test.txt

如果我们此时执行git diff,将没有实际的输出。这是预期的行为,因为执行 diff 的当前仓库没有变化。下面我们修改 diff_test.txt 文件的内容

$ echo "this is a diff example" > diff_test.txt

修改后,我们可以查看差异并分析输出。现在执行git diff将输出以下内容:

diff --git a/diff_test.txt b/diff_test.txt
index 6b0c6cf..b37e70a 100644
--- a/diff_test.txt
+++ b/diff_test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

git diff查看差异

现在让我们对diff输出内容进行以下拆分

1. 比较输入

diff --git a/diff_test.txt b/diff_test.txt

此行显示差异的输入源。我们可以 diff 对a/diff_test.txt和b/diff_test.txt 进行比较。

2. 元数据

index 6b0c6cf..b37e70a 100644

这一行显示了一些内部 Git 元数据。我们很可能不需要这些信息。此输出中的数字对应于 Git 对象版本哈希标识符。

3. 变化标记

--- a/diff_test.txt
+++ b/diff_test.txt

这些行是为每个差异输入源分配符号的图例。在这种情况下,更改a/diff_test.txt 用 --- 标记,更改b/diff_test.txt用+++符号标记。

4. 差异块

剩余的差异输出是差异“块”的列表。diff 仅显示文件中发生更改的部分。在我们当前的示例中,我们只有一个块,因为我们的文件比较简单。块有自己的粒度输出语义。

@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

第一行是块头。每个块都由一个包含在@@符号内的标头作为前缀。标题的内容是对文件所做更改的摘要。在我们的简化示例中,我们有 -1 +1 表示第一行发生了变化。在实际情况中,我们可能会看到如下标题:

@@ -34,6 +34,8 @@

在此标题示例中,从第 34 行开始提取了 6 行。此外,从第 34 行开始添加了 8 行。

高亮显示变化

git diff还有一个特殊的模式,用于以更好的粒度高亮显示更改:‐‐color-words。此模式通过空格标记添加和删除的行,然后对它们进行区分。

$ git diff --color-words
diff --git a/diff_test.txt b/diff_test.txt
index 6b0c6cf..b37e70a 100644
--- a/diff_test.txt
+++ b/diff_test.txt
@@ -1 +1 @@
this is agit difftest example

Git diff 高亮显示变化

现在输出仅显示已更改的颜色编码词。

比较二进制文件

我们迄今为止演示的示例中都是文本文件,git diff还可以在二进制文件上运行。不幸的是,默认输出不是很有帮助。

$ git diff
Binary files a/script.pdf and b/script.pdf differ

Git 有一个特性,它允许我们指定一个 shell 命令,在执行差异之前将二进制文件的内容转换为文本。不过,它需要一些设置。首先,我们需要指定一个 textconv 过滤器,描述如何将某种类型的二进制文件转换为文本。假设我们正在使用一个名为 pdftohtml 的简单程序(可通过自制软件获得)将 PDF 转换为可读的 HTML。我们可以通过编辑.git/config文件为单个仓库进行设置,也可以通过编辑全局设置~ /.gitconfig

[diff "pdfconv"]
textconv=pdftohtml -stdout

然后需要做的就是将一个或多个文件模式与我们的 pdfconv 过滤器相关联。我们可以通过在仓库的根目录中创建一个文件.gitattributes来完成此操作。

*.pdf diff=pdfconv

配置完成后,git diff将首先通过配置的转换器脚本运行二进制文件并比较转换器输出。可以应用相同的技术从各种二进制文件中获取有用的差异,例如:zip、jar等。

比较文件:git diff 文件

git diff命令可以传递一个显式文件路径选项。指定文件之后比较的范围将限定为指定的文件。

$ git diff HEAD ./path/to/file

比较两个不同提交之间的文件

git diff可以将 Git 引用传递给 diff 函数。一些示例引用是HEAD标签和分支名称。Git 中的每个提交都有一个提交 ID,我们可以执行 git log 查看提交ID. 然后将此提交 ID 传递给git diff.

$ git diff ed18a3a99be97518146857cbe1f00f82612dde68 33342da780e0efde4074aced294711a681a241c3

Git diff比较两次提交的差异

比较分支

比较来自两个分支的文件,需要将文件路径作为第三个参数传递给 git diff

$ git diff master dev hello.txt

Git diff比较两个分支的差异

查看笔记

扫码一下
查看教程更方便