【问题标题】:Git diff line differentiate between deletion and insertiongit diff 行区分删除和插入
【发布时间】:2022-11-24 01:22:55
【问题描述】:

当我将行插入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 的工作方式,但是有没有一种方法可以过滤掉或避免旧行显示为 deleted ?我只需要找到被删除的行,而不是被插入替换的行。

【问题讨论】:

  • 这不会发生在我身上。我做了那个序列,Git 显示了插入的一行。你运行的是哪个 Git 版本?
  • 您确定插入的是第 2 行而不是第 3 行吗?在您提供的示例中,您忘记了第 2 行行尾的 ,,所以也许您实际上插入了第 3 行而忽略了第 2 行以添加结尾逗号的形式进行了更改?如果不是这样,那么我敢打赌区别在于空格。使用突出显示它们的文本编辑器或使用十六进制编辑器非常仔细地检查这两个文件(插入行之前/之后)。
  • @quetzalcoatl 我仔细检查了一下,确实如此,git 正在考虑添加一个逗号的新行作为一个完全独立的添加,因为旧行没有逗号。我怎样才能排除这种情况?
  • 我将我和你的 cmets 复制到一个答案中,并在那里回答了你的新问题,这样其他人就可以看到它已被诊断/解决。

标签: git diff


【解决方案1】:

空格有变化:空格、制表符、回车( ), 新队 ( ). git diff -w 将忽略空格差异。

【讨论】:

    【解决方案2】:

    您确定插入的是第 2 行而不是第 3 行吗?在您提供的示例中,您忘记了第 2 行行尾的 ,,所以也许您实际上插入了第 3 行而忽略了第 2 行以添加结尾逗号的形式进行了更改?

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


    莱姆 回复:

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


    不幸的是,我认为你不能。改变就是改变。即使是一些容易被忽视或很容易变得微不足道的东西,比如空白,仍然是一种变化。

    有一个 -w 用于忽略空格克乐司注意到了,但这只是因为很多时候有制表符和空格, 对比 ,或者只是缩进问题。机器会关心,但人类不会,因此 -w 代表人类。

    但是逗号?这完全是一个文件格式相关的东西。在一种编程语言或数据格式中,添加逗号是很关键的,而在另一种语言或数据格式中,它只是一个细节。 Git 无法确定。

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      Diff Json

      蓝色连接器是“已移动”元素,即foo1 已在右侧向下移动了 1 行。 foo2 被检测为添加的元素(因此为绿色)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-28
        • 1970-01-01
        • 2011-08-17
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 2021-07-31
        • 1970-01-01
        相关资源
        最近更新 更多