Формат строки для последовательного разделения между записями, выводимыми `git log --pretty` - PullRequest
2 голосов
/ 19 сентября 2019

Я пытаюсь разработать строку формата для передачи на git log --pretty, чтобы каждая запись журнала заканчивалась сообщением о полной фиксации, но каждая запись журнала отделялась ровно одной пустой строкой.Проблема в том, что некоторые сообщения о полной фиксации заканчиваются символом новой строки, а некоторые - нет.

Например, допустим, у меня есть две фиксации, abc1234 и def5678, но только abc1234 содержит новую строкув конце сообщения о полной фиксации.Вывод необработанного содержимого коммита в командной строке будет выглядеть примерно так:

[prompt]$ git cat-file commit abc1234
(...)

Title FOO

Full commit message FOO
[prompt]$ git cat-file commit def5678
(...)

Title BAR

Full commit message BAR[prompt]$

Обратите внимание, как новое приглашение оболочки появляется в конце последней строки вывода, демонстрируя, что коммит def5678 делает not содержит символ новой строки в конце сообщения полной фиксации.

Допустим, def5678 является родителем abc1234, и я хочу вывести простой журнал, где каждая запись содержит толькокороткий хеш коммита, строка заголовка и сообщение полной фиксации.Я мог бы попробовать что-то вроде этого:

[prompt]$ git log --graph --pretty='commit %h%n%B' abc1234
* commit abc1234
| Title FOO
| 
| Full commit message FOO
|
* commit def5678
| Title BAR
|
| Full commit message BAR
* commit <parent of def5678>
(...)

Обратите внимание на интервал между записями журнала.Записи для abc1234 и def5678 разделены пустой строкой (за исключением символа графика), однако записи для def5678 и его родительского элемента не являются.

Как создать строку форматачтобы интервал был согласованным даже с непоследовательным завершением сообщений полной фиксации?Встроенные симпатичные форматы medium, full, fuller и email уже делают это, но я хочу иметь возможность создавать строки произвольного формата, чтобы делать то же самое.

I 'Мы экспериментировали с последовательностями %+B, %-B и % B (и их %b и %n эквивалентами), но я просто не могу получить постоянный интервал.

Яиспользуя Git 2.17.0, если это имеет значение.

Ответы [ 2 ]

2 голосов
/ 19 сентября 2019

Из справочной страницы git log:

-z

Отделите коммиты с помощью NUL вместо новых новых строк.

С этим вы можете четко отделить каждое сообщение.Затем для каждого сообщения добавьте в конец терминатор строки, только если в нем отсутствует один .

Пример:

fix-eol:

#!/bin/sh

lastchar="$(printf -- '%s\n' "$@" | tail -c1 | od -An -tx1)"

# output the input as is
printf -- '%s' "$@"

# print a newline only if it's missing
test "$lastchar" = ' 0a' && printf -- '\n'

Использование:

git log -z --pretty='commit %h%n%B' | xargs -0 -n1 ./fix-eol

Примечание: : мне не удалось сохранить сообщения коммита с отсутствующими ограничителями строки (кажется, что git исправляет их автоматически), но скрипт работал на такихфайлы.Кроме того, в зависимости от размера и содержания сообщений могут возникнуть проблемы, поскольку каждое сообщение передается в качестве аргумента (т. Е. Это был быстрый взлом).

PS :пример может быть улучшен во избежание использования отдельного скрипта.

0 голосов
/ 20 сентября 2019

Как @jthill упоминается в комментариях и выражается в git-log(1):

Если вы добавите - (знак минус) после % заполнителя, все подряд строки-фиды, непосредственно предшествующие раскрытию, удаляются тогда и только тогда, когда заполнитель расширяется до пустой строки.

Поэтому, если мы сможем найти последовательность форматирования %<token>, которая будет всегда развернув пустую строку, мы можем использовать %-<token>%n, чтобы заменить ноль или более последовательных символов новой строки одной строкой.Как выясняется, - это такая последовательность форматов: %C(), пустой селектор цвета.(Обычно круглые скобки содержат непустую строку, которая задает окраску, которая будет использоваться в выходных данных журнала. См. git-log(1) и git-config(1) для получения дополнительной информации.)

Тот факт, что %C() оценивается как пустоеСтрока вместо того, чтобы вызывать ошибку, кажется счастливой случайностью, а не чем-то, на что можно надеть шляпу, но, по крайней мере, для Git 2.17 она делает свое дело.На данный момент у меня достаточно информации, чтобы ответить на мой собственный вопрос.

Для обеспечения согласованного разделения между записями журнала, выводимыми по git log --pretty=<tformat>, где <tformat> может оценивать или не оценивать строку, заканчивающуюся насимвол новой строки, добавьте %-C()%n к <tformat>. Например:

[prompt]$ git log --graph --pretty='commit %h%n%B%-C()%n' abc1234
* commit abc1234
| Title FOO
| 
| Full commit message FOO
|
* commit def5678
| Title BAR
|
| Full commit message BAR
|
* commit <parent of def5678>
(...)
...