diff和git diff创建的补丁/文件有什么区别?

uinbv5nw  于 2023-06-20  发布在  Git
关注(0)|答案(1)|浏览(121)

我想知道diffgit-diff创建的文件/补丁的格式有什么不同。
我知道在diff中有3个(“正常”,“紧凑”-c和“统一”-u)。
但是,可能会有一些差异,在某些情况下,你不能自由交换git diffdiff。所以:

  1. git diffdiff是否可以用于同一个文件取决于什么?
    1.格式之间有什么区别?
    1.如果您不能交换命令(参见1.),如何将文件转换为另一种格式,以便您可以将它们与另一个命令一起使用?
    1.如果可以交换命令(请参见1.):这样做是否值得推荐?
    1.这两个命令创建的文件是否有其他显著差异?
mpbci0fu

mpbci0fu1#

  1. git diffdiff是否可以用于同一个文件取决于什么?
    简单地说,如果文件在git repo工作树中,那么你就可以使用git diff来显示该文件的更改(针对git repo引用的同一文件,如index或blob对象)。
    这与'diff'不同,它比较 * files *(这意味着你需要两个文件,而不是在git仓库中使用git diff时只需要一个文件)
    正如hvd在评论中指出的那样:
    You can use git diff outside any work tree and pass it two files
    因此,您可以在几乎任何可以使用diff的情况下使用git diff
    反之则不然
git diff --color-words --no-index file1 file2

1.格式之间有什么区别?
git diff可以模拟任何diff格式(unified,raw,...)。
它也有特定于git的格式(--summary--stat,...)
参见:

一个git diff将包含一个git header,带有一个“相似性索引”。
每个差异块的块显示为very similar to a diff -u
1.如果您不能交换命令(参见1.),如何将文件转换为另一种格式,以便您可以将它们与另一个命令一起使用?
您可以将git diff转换为raw格式,或使用raw格式进行修补:--patch-with-raw
相反是可能的:you can apply a diff to a git repo
1.如果可以交换命令(请参见1.):这样做是否值得推荐?
如果你没有安装git的话(参见the previous example
1.这两个命令创建的文件是否有其他显著差异?
否:应用diffgit diff生成的修补程序的结果应该相同。
警告:Git 2.42(Q3 2023)修复了一个bug:"diff"命令族的"-s"(silent,squelch)选项没有与指定输出格式的其他选项很好地交互。
这已被清理,以便它将清除之前给出的所有格式选项。
参见commit 9d484b9(2023年5月5日)由Junio C Hamano ( gitster )
(由Junio C Hamano -- gitster --合并于commit 6901ffe,2023年6月13日)

diff:修复“-s”选项和其他选项之间的交互

Sergey Organov注意到并报告“--patch --no-patch --raw”的行为与“--raw”不同。
事实证明,在实现和文档中存在一些有趣的bug。

  • 首先,“--no-patch”的文档不清楚,它可以被解读为“--no-patch”,而不是其他东西。

自从在d09cd15(“diff:allow --no-patch as synonym for-s ",2013 - 07 - 16,Git v1.8.4-rc0--merge)是作为" -s "的同义词,所以" --raw --patch --no-patch应该没有产生任何输出,但它可以被(错误)读取以允许只显示"--raw"输出。
1.然后“-s”和其他格式选项之间的交互实现得很差。
现代版本的Git使用一个位来表示格式选项,如“--patch”,“--stat”在单个output_format字中,但由于历史原因,“-s”也被表示为同一字中的另一个位。
这会导致两个有趣的bug发生,我们有两个X-<。
1.在设置格式位后,然后使用“-s”设置NO_OUTPUT,处理另一个“--<format>”选项的代码将丢弃NO_OUTPUT位,以允许再次显示输出。
但是,处理“-s”的代码只设置了NO_OUTPUT,而没有取消之前设置的格式位,因此在看到第二个“--<format>”选项时,显示了之前的格式位。这是谢尔盖观察到的问题。
1.在使用"-s"设置NO_OUTPUT后,处理"--<format>"选项的代码可能会忘记取消设置NO_OUTPUT,使命令仍然保持静默。
很容易将“--no-patch”的含义更改为“仅禁用补丁格式输出”,并将“-s”重新实现为“不显示任何内容”,但这将是最终用户可见的行为变化。
让我们修复这些位的交互,首先使“-s”按预期工作。
修复在概念上非常简单。

  • 每当我们设置DIFF_FORMAT_FOO时,因为我们看到“--foo”选项(例如DIFF_FORMAT_RAW是在给定"--raw"选项时设置的),我们确保删除DIFF_FORMAT_NO_OUTPUT

我们在某些选项中忘记这样做,导致了上面的(2)。

  • 在处理“-s”选项时,我们不应该只设置DIFF_FORMAT_NO_OUTPUT位,而应该清除其他DIFF_FORMAT_*位。我们没有这样做,而是保留了之前看到的选项设置的格式位,导致了上面的(1)。

丢失NO_OUTPUT位并将output_format字替换为0更有诱惑力,但这将破坏“git show”机制。(man)使用默认为--patch输出,其中使用“-s”告知命令静默和在命令行上没有指定输出格式之间的区别很重要,并且在命令行上给出的显式输出格式不应与默认的“--patch”格式“组合”。
因此,虽然我们不能丢失NO_OUTPUT位,但作为后续工作,我们可能希望将其替换为OPTION_GIVEN位,并且:

  • 制作“--patch”、“--raw”等。

为每种格式设置DIFF_FORMAT_$format位和DIFF_FORMAT_OPTION_GIVEN位。
--no-raw”等
将设置DIFF_FORMAT_$format位,但仍然记录我们通过设置DIFF_FORMAT_OPTION_GIVEN位从命令行看到一个选项的事实。

  • 使“-s”(及其同义词“--no-patch”)清除所有其他位,并仅设置DIFF_FORMAT_OPTION_GIVEN位。

我怀疑这会使代码更干净,而不会打破最终用户的期望。
一旦这样做了,将“--no-patch”转换为“--patch”的对应物,就像“--no-raw”只击败了早期的“--raw”一样,在代码级将非常简单。
迁移最终用户期望的社会成本可能太大了,但至少“GIVEN”位清理本身可能是值得的。
diff-options现在在其手册页中包括:
抑制差分机器的所有输出。
对于像git show这样默认显示修补程序的命令非常有用,可以抑制它们的输出,或者取消前面在命令行上以别名显示的--patch--stat等选项的效果。

相关问题