Git diff 行区分删除和插入

问题描述 投票:0回答:3

当我将行插入

file.json
时,git 也会将旧行视为已删除。例如,将
"foo2": "bar2"
插入第 2 行:

old
1 {
2   "foo1": "bar1"
3 }

new 
1 {
2   "foo2": "bar2"
3   "foo1": "bar1"
4 }

当我运行以下命令时,仅过滤掉以

-
+
开头的行:

git diff -U0 ..origin/main -- path/to/file.json | grep '^[+-][^+-]''

这是结果:

-  "foo1": "bar1"
+  "foo2": "bar2"
+  "foo1": "bar1"

我知道这就是 git 的工作原理,但是有没有办法可以过滤掉或避免旧行显示为已删除?我只需要找到被删除的行,而不是被插入替换的行。

git diff
3个回答
1
投票

空白有变化:空格、制表符、回车( ), 新队 ( )。

git diff -w
将忽略空白差异。


0
投票

您确定插入的是第 2 行而不是第 3 行吗?在您提供的示例中,您在第 #2 行的行末尾忘记了

,
,所以也许您实际上插入了第 #3 行并忽略了第 #2 行以添加结束逗号的形式进行了更改?

如果情况并非如此,那么我打赌差异在于空格。使用突出显示它们的文本编辑器或十六进制编辑器非常仔细地检查这两个文件(在插入行之前/之后)。


Lem 回复:

我仔细检查了一下,确实是这样,git 正在考虑 添加了逗号的新行作为完全独立的添加,因为 旧行没有逗号。 我该如何排除这种情况?


不幸的是,我认为你不能。改变就是改变。即使是一些容易被忽视的东西或一些容易被琐碎的东西,比如空白,仍然是一个变化。

有一个

-w
用于忽略空格,如 Klox 指出的那样,但这只是因为很多时候存在制表符与空格, 与 ,或者只是缩进问题。机器会关心,但人类不会,因此对人类来说
-w

但是逗号?这完全取决于文件格式。在一种编程语言或数据格式中,添加逗号至关重要,而在另一种编程语言或数据格式中,这只是一个细节。 Git 无法确定。

如果您非常需要差异来消除此类噪音,我可以作为潜在的解决方案:

  • 您知道哪些情况会导致问题,所以如果您可以控制生成它们的事物,您可以以某种方式确保所有行都以安全的非逗号方式添加,始终位于列表的开头或中间,永远不会在最后。

  • 您也知道问题是什么,并且它的定义现在已经定义得很好并且也很容易找到(逗号后跟换行符)。您可以在比较之前通过预处理器运行文件,小工具或脚本可以删除所有此类项目分隔逗号,或者在每个列表的末尾添加一个逗号;然后比较这些清理后的文件。 JSON 是一个很好的例子,因为实际数据中不可能有逗号换行序列,因为带有换行的字符串数据将被编码为 或者 不是字面上的换行符。因此,逗号换行序列始终是列表项分隔符(数组中的项、对象中的道具),而不是真正的“数据有效负载”。

  • Git

    diff
    被设计为多种语言/等的通用文本比较工具。但它已经尽力了。它不可能拥有任何情况下都想要拥有的所有功能。除了默认的差异之外,您还可以有其他差异,例如 JPG 文件的图像差异、Excel/Word 文件的复杂差异等。它们只是独立的工具,默认情况下不会随 git 客户端安装一起提供。您可以将 git 客户端设置为使用另一个实用程序来为您生成差异,一些实用程序知道如何更好地比较 JSON,一个 json-differ 知道这些地方的命令是不相关的。但是,我不知道这样的实用程序。


0
投票

虽然这是一个简单的情况,只要在

,
之后添加尾随
bar1
,git 就可以处理,但 git 并不真正理解 json 的结构来生成更好的差异。我个人为此使用 DiffLens VS Code 扩展(免费:https://marketplace.visualstudio.com/items?itemName=DiffLens.difflens)。我刚刚在我的机器上快速检查了这一点。这就是它的样子:

Diff Json

蓝色连接器是“移动”元素,即

foo1
已在右侧向下移动 1 行。
foo2
被检测为添加元素(因此呈绿色)

© www.soinside.com 2019 - 2024. All rights reserved.