git diff块头中的摘录来自哪里?

eqoofvh9  于 2023-02-28  发布在  Git
关注(0)|答案(1)|浏览(78)

当我在C#文件上使用git diff时,我看到了如下内容:

diff --git a/foo.cs b/foo.cs
index ff61664..dd8a3e3 100644
--- a/foo.cs
+++ b/foo.cs
@@ -15,6 +15,7 @@ static void Main(string[] args)
                    string name = Console.ReadLine();
             }
             Console.WriteLine("Hello {0}!", name);
+            Console.WriteLine("Goodbye");
         }
     }
 }

块头行包含当前方法(static void Main(string[] args))的第一行,这很好。但是它似乎不是很可靠...我看到很多情况下它不工作。
所以我想知道,这个摘录是从哪里来的?git diff是否以某种方式识别语言语法?是否有办法定制它?

ymzxtsji

ymzxtsji1#

有办法定制吗?
配置在.gitattributes的“定义自定义块头”部分中定义:
首先,在.gitattributes中,您将为路径分配diff属性。

*.tex diff=tex

然后,您可以定义一个“diff.tex.xfuncname“配置来指定一个正则表达式,该表达式与您希望显示为块头“TEXT“的行匹配。

[diff "tex"]
   xfuncname = "^(\\\\(sub)*section\\{.*)$"

注意:配置文件解析器只使用了一级反斜杠,因此您需要将反斜杠加倍;上面的模式选择了一个以反斜杠开头的行,并且在该行的末尾零次或多次出现sub,然后是section,最后是左括号。
有一些内置模式可以简化这一过程,tex就是其中之一,因此您不必在配置文件中编写上述内容(您仍然需要通过.gitattributes使用属性机制来启用此功能)。
(“csharp”是当前内置模式的一部分)
这段节选从何而来?
git diff能识别语言语法吗?
最初,该算法对于函数名检测是相当粗糙的:
参见commit acb7257(Git 1.3.0,2006年4月,作者为Mark Wooding)

xdiff:在块头中显示函数名。

内置的diff生成器的速度是不错的;但是diff -p显示的函数名 * 真的 * 很好。而且我讨厌不得不选择。
因此,我们破解xdiff来查找函数名并打印它们。
目前,函数名是由一种特别愚蠢的算法解析的:它只是试图在'old'文件中找到一行,从大块开始之前,其第一个字符看起来似乎是可信的。
它是用get_func_line()改进的,get_func_line()本身来自commit f258475(Git 1.5.3,2007年9月,作者Junio C Hamano(gitster))
您可以在中看到,将测试t/t4018-diff-funcname.sh提交到Test custom diff函数名称模式。

基于每个路径属性的块标头选择。

这使得“diff -p“块头可以通过gitattributes机制进行自定义。
它基于Johannes早期的补丁,该补丁允许定义一个用于所有操作的regexp。
到达用于定义块头的regexp的机制与gitattributes的其他用法相同。
您分配一个属性funcname(因为“diff -p“通常使用补丁所涉及的函数的名称作为块头),一个简单的字符串值。
这可以是内置模式的名称之一(当前定义了java“),也可以是自定义模式名称,可以从配置文件中查找。

(in .gitattributes)
 *.java   funcname=java
 *.perl   funcname=perl

 (in .git/config)
 [funcname]
   java = ... # ugly and complicated regexp to override the built-in one.
   perl = ... # another ugly and complicated regexp to define a new one.

当前的xfuncname语法是在2008年10月Git www.example.com上的commit 45d9414中介绍1.6.0.3的,作者是布兰登凯西

diff.*.xfuncname,使用“扩展”正则表达式进行块头选择

目前,可以通过在配置文件中设置diff.*.funcname选项来自定义由“diff -p”生成的块标头。“funcname”选项采用基本正则表达式。此功能是使用GNU正则表达式库设计的,默认情况下,即使在基本正则表达式模式下,也允许使用某些扩展正则表达式运算符的反斜线版本。例如,以下字符在使用反斜杠时,将根据扩展正则表达式规则进行解释:一个米27纳米一个x、一个米28纳米一个x和一个米29纳米一个x。
因此,内置的funcname模式是使用一些扩展的正则表达式操作符创建的。
其他更严格遵守POSIX规范的平台在Basic Regular Expression模式下不解释反斜线扩展RE操作符,这导致内置funcname模式的模式匹配在这些平台上失败。

引入一个使用扩展正则表达式的新选项“xfuncname”,并公布它 * 而不是 * funcname

由于大多数用户都使用GNU平台,因此大多数funcname模式都是在那里创建和测试的。
只公布xfuncname应该有助于避免创建不可移植的模式,这些模式可以在GNU正则表达式中使用,但在其他地方不能使用。
此外,扩展正则表达式与基本RE相比可能不那么难看和复杂,因为许多常见的特殊运算符不需要被反斜线。
例如,GNU Basic RE:

^[    ]*\\(\\(public\\|static\\).*\\)$

成为以下扩展RE:

^[    ]*((public|static).*)$

最后,它被扩展为commit 14937c2,for git 1.7.8(2011年12月),作者是René Scharfe。

diff:添加选项以将整个函数显示为上下文

将选项-W/--function-context添加到git diff
它类似于git grep的相同选项,并扩展了change hunks的上下文,以便显示整个周围的函数。
这种“自然”的背景可以使变化得到更好的理解。
Git 2.15(2017年第四季度)仍在调整中
用于检测HTML的“函数头”的内置模式与没有任何属性的<H1>..<H6>元素不匹配,此问题已得到修复。
在2.15之前,它无法匹配<h1>...</h1>,而<h1 class="smth">...</h1>匹配。
参见commit 9c03cac(2017年9月23日),作者为Ilya Kantor ( iliakan )

(由Junio C Hamano -- gitster --合并至commit 376a1da,2017年9月28日)
检测函数边界的模式称为**xfuncref**。
参见Łukasz Niemier ( hauleth )commit a807200(2019年11月8日)。
(由Junio C Hamano -- gitster --合并到commit 376e730中,2019年12月1日),适用于Git 2.25(2020年第一季度)

userdiff:将Elixir添加到支持的userdiff语言

签署人:乌卡斯·尼米耶
确认人:Johannes Sixt
添加了对Elixirxfuncref的支持,该语言是在Erlang虚拟机(BEAM)上运行的Ruby类语言。
以及:
参见commit d1b1384(2019年12月13日)。
(由Junio C Hamano -- gitster --合并至commit ba6b662,2019年12月25日)

userdiff:从elixir正则表达式中删除空子表达式

签署人:埃德·马斯特
审核人:杰夫·金
协助人:约翰内斯·西克特
正则表达式在FreeBSD上编译失败。
还要添加/* -- */标记来分隔为PATTERNS()宏指定的两个regex条目,以使其与其他内容类型的模式一致。
Markdown文档的userdiff模式已在Git 2.27(Q2 2020)中添加。
参见commit 09dad92(2020年5月2日)。
(由Junio C Hamano -- gitster --合并至commit dc4c393,2020年5月8日)

userdiff:支持降价

签署人:阿什·霍兰德
确认人:Johannes Sixt
Markdown文档通常与源代码放在一起,有更好的文档更改上下文是很有用的;另请参见commit 69f9c87d4("userdiff:添加对喷泉文档的支持",2015年7月21日,Git v2.6.0-rc0--merge列于batch #1中)。
该模式基于CommonMark规范0.29第4.2节https://spec.commonmark.org/,但不匹配空标题,因为在块标题中看到它们可能没有用。
只支持ATX标题,因为检测setext标题需要在模式匹配之前打印该行,或者匹配多行模式。word-diff模式与HTML的模式相同,因为许多Markdown解析器接受内联HTML。
在Git 2.30(Q1 2021)中,userdiff模式学会了识别POSIX shell和bash中的函数定义。
参见commit 2ff6c34(2020年10月22日),作者为Victor Engmark ( l0b0 )
(由Junio C Hamano -- gitster --合并至commit 292e53f,2020年11月2日)

userdiff:支持Bash

签署人:维克托·恩格马克
确认人:Johannes Sixt
支持POSIX、bashism和混合函数声明、所有四种复合命令类型、尾随注解和混合空格。
尽管Bash允许locale-dependent characters in function names,但为了简单起见,只检测包含POSIX. 1 - 2017允许的字符的函数名。
这应该涵盖绝大多数用例,并产生系统无关的结果。
由于必须指定一个单词模式,但没有简单的方法来知道默认的单词模式,因此使用默认的IFS字符作为起始字符。以后的补丁可以改进这一点。
gitattributes现在在其手册页中包括:

  • bash适用于Bourne-Again SHell语言的源代码。

涵盖POSIX shell函数定义的超集。
在Git 2.32(Q2 2021)中,添加了针对"Scheme"的userdiff模式。
参见Atharva Raykar ( tfidfwastaken )(2021年4月8日)。
(由Junio C Hamano -- gitster --合并至commit 6d7a62d,2021年4月20日)

userdiff:添加方案支持

签署人:阿萨瓦·雷卡尔
为类Scheme语言添加一个diff驱动程序,它可以识别顶级和本地define表单,无论是函数定义、绑定、语法定义还是用户定义的define-xyzzy表单。
还支持R6RS library表单、module表单以及Racket(PLT方案)中使用的类和结构声明。
也支持替代的"def"语法,如Gerbil Scheme中的语法,如defstruct、defsyntax等。
选择define表单作为块头的基本原理是因为它通常是定义程序结构的唯一重要表单,并且schemer使用本地函数定义来隐藏其可见性是一种常见模式,因此不仅仅是顶层的define表单感兴趣。
Schemers还使用宏来扩展语言,以提供自己的定义形式(例如,类似于define-test-suite的形式),这些形式也在块头中捕获。
由于使用module+class*等形式的变体扩展语法是常见的做法,因此这些变体也得到了支持。
regex这个词是一个尽力符合R7RS(第2.1节)有效标识符、符号和数字的尝试。
gitattributes现在在其手册页中包括:

  • scheme适用于Scheme语言的源代码。

在Git 2.33(2021年第三季度)中,C#的userdiff模式学习了标记"record"。
参见Julian Verdurmen ( 304NotModified )commit c4e3178(2021年3月2日)。
(由Junio C Hamano -- gitster --合并至commit f741069,2021年7月8日)

userdiff:添加对C#记录类型的支持

签署人:朱利安·韦尔杜尔曼
审核人:约翰内斯·申德林
在C#9中添加记录
代码示例:

public record Person(string FirstName, string LastName);

有关详细信息,请参见https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9
在Git 2.34(Q4 2021)中,"java"语言的userdiff模式已经更新。
参见Tassilo Horn ( tsdh )commit a8cbc89(2021年8月11日)。
(由Junio C Hamano -- gitster --合并至commit a896086,2021年8月30日)

userdiff:改进Java块头正则表达式

签署人:塔西洛·霍恩

目前,如果方法具有限定返回类型、数组返回类型或泛型返回类型,则git diffman)块头显示错误的方法签名,因为正则表达式不允许返回类型中包含点(.)[]<>
此外,类型参数声明也无法匹配。
添加几个t4018测试,针对不同情况Assert正确的块头:

  • 枚举常数变化
  • 更改具有绑定类型参数的泛型方法
  • 带通配符的泛型方法的更改
  • 嵌套类中的字段更改

而且,在Git 2.34(Q4 2021)中, C++ 的userdiff模式也得到了更新。
参见第一次电子邮件发送的第59次电子邮件(2021年10月24日)、第一次电子邮件发送的第60次电子邮件、第一次电子邮件发送的第61次电子邮件、第一次电子邮件发送的第62次电子邮件(2021年10月10日)和第一次电子邮件发送的第63次电子邮件、第一次电子邮件发送的第64次电子邮件、第一次电子邮件发送的第65次电子邮件(2021年10月8日)。
(由Junio C Hamano -- gitster --合并到commit f3f157f,2021年10月25日)
例如:

userdiff-cpp:允许在数字中使用数字分隔单引号

签署人:约翰内斯·西克特
从C++17开始,单引号可以用作数字分隔符:

3.141'592'654
1'000'000
0xdead'beaf

让cpp驱动程序的regex一词知道它,这样数字就不会在单引号处拆分成单独的标记。
在Git 2.40(2023年第一季度)中,userdiff包含了针对Java语言的regexp更新。
参见Andrei Rybak ( rybak )commit 93d52edcommit 575e6fccommit 39226a8(2023年2月8日)。
(由Junio C Hamano -- gitster --合并至commit 4a6e6b0,2023年2月15日)

userdiff:支持Java密封类

签署人:安德烈·雷巴克
审核人:约翰内斯·西克特
Java 17中添加了一种新的类--密封类(参见"JEP 409: Sealed Classes" ")。1
此功能包括几个可能出现在类声明中的新关键字。
类名前面的新修饰符:"sealed"和"non-sealed",以及由关键字"permises"标记的类名之后的子句。
userdiff.c中的当前正则表达式集已经允许修饰符"sealed"和"permits"子句,但不允许修饰符"non-sealed",这是Java中第一个带连字符的关键字(请参见"JEP draft: Keyword Management for the Java Language")。
允许在类型名称前面的单词中使用连字符以匹配"non-sealed"修饰符。

相关问题