git diff
比对功能接受两个输入数据集并输出它们之间的变更。git diff
是一个多用途 Git 命令,它在执行时会在 Git 数据源上运行比对功能。这些数据源可以是提交、分支、文件等。本文档将讨论 git diff
的常见调用和比对工作流模式。git diff
命令通常与 git status
和 git log
一起使用,用于分析 Git 代码存储库的当前状态。
读取比对:输出
原始输出格式
以下示例将在一个简单的代码存储库中执行。代码存储库是使用以下命令创建的:
$:> 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/kev/code/test/.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_test.txt
文件后,我们可以变更该文件的内容以开始尝试比对输出。
相关资料
Git 分支
查看解决方案
了解 Bitbucket Cloud 的 Git
$:> echo "this is a diff example" > diff_test.txt
执行此命令将变更 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
现在我们来看看比对输出的更详细细分。
1. 比较输入
diff --git a/diff_test.txt b/diff_test.txt
此行显示比对的输入源。我们可以看到 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. 比对区块
剩下的比对输出是比对“区块”的列表。比对仅显示文件中变更的部分。在我们当前的示例中,我们只有一个区块,因为我们正在处理一个简单的场景。区块有自己的精细输出语义。
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example
第一行是区块标头。每个区块前面都有一个包含 @@
符号的标头。标头的内容是对文件所做变更的摘要。在我们的简化示例中,我们有 -1 +1,表示第一行发生了变更。在更真实的比对中,您会看到一个标头,如下所示:
@@ -34,6 +34,8 @@
在此标头示例中,从第 34 行开始提取了 6 行。此外,从第 34 行开始,还添加了 8 行。
比对区块的其余内容显示最近的变更。每个变更的行前面都有一个 +
或 -
符号,表示变更来自哪个版本的比对输入。正如我们之前讨论的那样,-
表示与 a/diff_test.txt
相比发生的变更,+ 表示与 b/diff_test.txt
相比发生的变更。
突出显示变更
1. git diff --color-words
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
现在,输出仅显示已变更的用颜色编码的字。
2. git diff-highlight
如果您克隆 git 源代码,就会发现一个名为 contrib 的子目录。它包含了一大堆与 git 相关的工具以及其他尚未升级为 git core 的有趣内容。其中一个是名为 diff-highlight 的 Perl 脚本。diff-highlight 将匹配的比对输出行配对,并突出显示已变更的子字片段。
$:> git diff | /your/local/path/to/git-core/contrib/diff-highlight/diff-highlight
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
还可以在二进制文件上运行。不幸的是,默认输出不是很有用。
$:> 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
将首先通过配置的转换器脚本运行二进制文件,然后对转换器输出进行比对。同样的技术可以用来从各种二进制文件中获得有用的比对,例如:zips、jar 和其他归档:使用 unzip-l
(或类似文件)代替 pdf2html 将显示在提交图像之间添加或删除的路径:exiv2 可用于显示元数据变更,例如图像尺寸文档:存在用于将 .odf、.doc 和其他文档格式转换为纯文本的转换工具。必要时,字符串通常适用于不存在正式转换器的二进制文件。
比较文件:git diff 文件
可以向 git diff
命令传递明确的文件路径选项。文件路径传递给 git diff
时,比对操作的作用域将限定为指定文件。以下示例演示了这种用法。
git diff HEAD ./path/to/file
调用时,此示例的作用域为 ./path/to/file
,它会将工作目录中的具体变更与索引进行比较,显示尚未暂存的变更。默认情况下,git diff
将执行与 HEAD
的比较。在上面的 git diff ./path/to/file
示例中省略了 HEAD
具有同样的效果。
git diff --cached ./path/to/file
使用 --cached
选项调用 git diff
时,比对会将暂存的变更与本地存储库进行比较。--cached
选项与 --staged
同义。
比较所有变更
在没有文件路径的情况下调用 git diff
将比较整个存储库中的变更。以上是文件特定的示例,可以在没有的情况下调用 ./path/to/file
参数,并且在本地代码存储库中的所有文件中具有相同的输出结果。
自上次提交以来的变更
默认情况下,git diff
会显示自上次提交以来所有未提交的变更。
git diff
比较两个不同提交之间的文件
git diff
可以将 Git 引用传递给提交进行比对。一些示例引用包括 HEAD
、标记和分支名称。Git 中的每个提交都有一个提交 ID,您可以在执行 GIT LOG
时获得这个提交 ID。您也可以将这个提交 ID 传递给 git diff
。
git log --pretty=oneline
957fbc92b123030c389bf8b4b874522bdf2db72c add feature
ce489262a1ee34340440e55a0b99ea6918e19e7a rename some classes
6b539f280d8b0ec4874671bae9c6bed80b788006 refactor some code for feature
646e7863348a427e1ed9163a9a96fa759112f102 add some copy to body
$:> git diff 957fbc92b123030c389bf8b4b874522bdf2db72c ce489262a1ee34340440e55a0b99ea6918e19e7a
比较分支
比较两个分支
像所有其他引用输入一样将分支与 git diff
进行比较
git diff branch1..other-feature-branch
此示例引入了点运算符。此示例中的两个点表示比对输入是两个分支的尖端。如果省略点并在分支之间使用空格,也会产生同样的效果。此外,还有一个三点运算符:
git diff branch1...other-feature-branch
三点运算符通过变更第一个输入参数 branch1
来启动比对。它将 branch1
变更为两个比对输入之间共享的共同祖先提交引用,即 branch1
和其他功能分支的共享祖先。最后一个参数输入参数保持不变,就像其他功能分支的尖端一样。
比较来自两个分支的文件
要跨分支比较特定文件,请将该文件的路径作为第三个参数传递给 git diff
git diff main new_branch ./diff_test.txt
摘要
本页讨论了 Git 比对流程和 git diff
命令。我们讨论了如何读取 git diff
输出以及输出中包含的各种数据。提供了有关如何通过突出显示和颜色更改 git diff
输出的示例。我们讨论了不同的比对策略,例如如何比对分支中的文件和特定的提交。除了 git diff
命令外,我们还使用了 git log
和 git checkout
。
分享此文章
下一主题
推荐阅读
将这些资源加入书签,以了解 DevOps 团队的类型,或获取 Atlassian 关于 DevOps 的持续更新。