Git diff 比较更改
git diff
是一个多用途的 Git 命令,执行时会在 Git 数据源上运行 diff 函数。这些数据源可以是一次提交、一个分支或文件等。本章节将讨论常见的git diff工作流模式调用和不同的工作流模式。git diff命令通常与git status 、git 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
现在让我们对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
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 master dev hello.txt