Откуда берется отрывок в заголовке git diff hunk?

Когда я использую 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");
         }
     }
 }

Строка заголовка hunk содержит первую строку текущего метода (static void Main(string[] args)), что отлично. Однако это не кажется очень надежным... Я вижу много случаев, когда он не работает.

Итак, мне было интересно, откуда взялся этот отрывок? Может ли git diff распознать синтаксис языка? Есть ли способ его настроить?

Ответ 1

Есть ли способ его настроить?

Конфигурация определена в .gitattributes, раздел "Определение пользовательского заголовка hunk" :

Сначала, в .gitattributes, вы должны назначить атрибут diff для путей.

*.tex   diff=tex

Затем вы должны определить конфигурацию "diff.tex.xfuncname", чтобы указать регулярное выражение, которое соответствует строке, которую вы хотели бы отображать как заголовок hunk "TEXT". Добавьте раздел в файл $GIT_DIR/config (или $HOME/.gitconfig), например:

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

Примечание. Единственный уровень обратных косых черт, потребляемый парсером конфигурационного файла, поэтому вам нужно удвоить обратную косую черту; вышеописанный шаблон выбирает линию, начинающуюся с обратного слэша, и ноль или более вхождений подсекции с последующим разделом, за которым следует открытая скобка, до конца строки.

Есть несколько встроенных шаблонов, чтобы сделать это проще, а tex является одним из них, поэтому вам не нужно писать выше в вашем файле конфигурации (вам все равно нужно включить его с помощью механизма атрибутов, через .gitattributes).

('csharp' является частью текущих встроенных шаблонов)




Откуда взялся этот отрывок?
Может ли git diff распознать синтаксис языка?

Первоначально алгоритм был довольно грубым для определения имени функции:
См. commit acb7257 (Git 1.3.0, апрель 2006, автор Марк Вудинг)

xdiff: Показать имена функций в заголовках hunk.

Скорость встроенного генератора рассеяния хороша; но имена функций показанные diff -p, действительно приятны. И я не хочу выбирать.
Итак, мы взломаем xdiff, чтобы найти имена функций и напечатать их.

Имена функций анализируются особенно глупым алгоритмом на момент: он просто пытается найти строку в "старом" файле, начиная с начало рукопожатия, чей первый персонаж выглядит правдоподобным. Тем не менее, это наиболее определенно начало.


Он был усовершенствован get_func_line(), сам из commit f258475 (Git 1.5.3, сентябрь 2007, автор Junio ​​C Hamano (gitster))

Вы можете увидеть, что в тесте t/t4018-diff-funcname.sh проверить тестовые шаблоны имен функций.

Выбор заголовка заголовка на основе атрибута per-path.

Это делает заголовки "diff -p" настраиваемыми с помощью механизма gitattributes.
Он основан на раннем патче Йоханнеса, который позволил определить один regexp, который будет использоваться для всего.

Механизм для получения регулярного выражения, используемого для определения заголовка hunk это то же самое, что и другое использование gitattributes.
Вы назначаете атрибут funcname (потому что "diff -p" обычно использует имя функции, которую патч относится к заголовку hunk), простое строковое значение.
Это может быть одно из имен встроенного шаблона (в настоящее время определено 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 введен в commit 45d9414, Git 1.6.0.3, октябрь 2008, автор Brandon Casey

diff.*.xfuncname, который использует расширенное регулярное выражение для выбора заголовка hunk

В настоящее время заголовки заголовков, создаваемые 'diff -p', настраиваются установив опцию diff.*.funcname в файле конфигурации. Опция 'funcname' принимает основное регулярное выражение. Эта функциональность была разработана с использованием библиотеки регулярных выражений GNU, которая по умолчанию позволяет использовать backslashed версии некоторых расширенных операторов регулярных выражений даже в режиме Basic Regular Expression. Например, следующие символы при обратном сбрасывании интерпретируются в соответствии с расширенными правилами регулярных выражений: ?, + и |.
Таким образом, встроенные шаблоны funcname были созданы с использованием некоторых расширенных операторы регулярных выражений.

Другие платформы, которые более строго придерживаются спецификации POSIX, не интерпретировать расширенные операторы RE с обратной связью в Basic Regular Expression Режим. Это приводит к совпадению шаблонов для встроенных шаблонов funcname. сбой на этих платформах.

Ввести новую опцию 'xfuncname', которая использует расширенные регулярные выражения, и рекламировать ее вместо funcname.
Поскольку большинство пользователей находятся на платформах GNU, большинство шаблонов funcname создаются и тестируются там. Только реклама xfuncname должна помочь избежать создания не переносных шаблонов, которые работают с регулярным выражением GNU, но не в другом месте.

Кроме того, расширенные регулярные выражения могут быть менее уродливыми и сложный по сравнению с базовым RE, поскольку многие обычные специальные операторы делают не требует обратной защиты.

Например, GNU Basic RE:

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

становится следующим расширенным RE:

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

Наконец, он был расширен с помощью commit 14937c2, для Git 1.7.8 (декабрь 2011), автором которого является Рене Шарф.

diff: добавить опцию для отображения целых функций как контекста

Добавьте опцию -W/--function-context в git diff.
Это похоже на ту же опцию git grep и расширяет контекст смены изменений, чтобы показать всю окружающую функцию.
Этот "естественный" контекст может позволить лучше понять изменения.


Он все еще исправляется в Git 2.15 (Q4 2017)

Встроенный шаблон для обнаружения "заголовка функции" для HTML не соответствуют <H1>..<H6> элементам без каких-либо атрибутов, которые имеют были исправлены.

До версии 2.15 он не соответствовал <h1>...</h1>, а <h1 class="smth">...</h1> - совпадению.

См. commit 9c03cac (23 Sep 2017) Илья Кантор (iliakan).
(слияние Junio ​​C Hamano - gitster - в commit 376a1da, 28 Sep 2017)