Могу ли я добавить метаданные в git? Или я могу скрыть некоторые теги в gitk

Я хочу связать пользовательские метаданные с git commit. В частности, для записи идентификатора обзора из обзора кода, но это может быть что угодно. Теги кажутся естественным способом сделать это, но я ожидаю получить обзор для каждой фиксации, и я не хочу загромождать gitk множеством тэгов. Есть ли какой-то другой механизм для добавления пользовательских метаданных? Могу ли я сделать определенные теги невидимыми? Если бы я мог сказать gitk не показывать теги, соответствующие некоторому шаблону или RE, это, вероятно, сработает, но я не вижу способа сделать это.

Ответ 1

Именно то, что git notes для.

Ответ 2

ГИТ-ноты

С помощью git notes вы можете добавить "заметку" в коммит. Вы также можете добавить их к другим объектам Git, но давайте просто сосредоточимся на коммитах, поскольку именно об этом и идет речь.

Заметка является объектом Git и в принципе может быть "что угодно" (произвольные данные). Но хорошо сфокусируйтесь на чем-то простом и текстовом для наших целей.

Пример: идентификатор отзыва

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

Review-id: 42

Так что это фактически пара ключ-значение. Добавим приведенную выше строку к текущему коммиту:

git notes add -m "Review-id: 42"

Если вы запустите git log заметка будет показана в строке: († 1)

Author: Victor Version Control <[email protected]>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes:
    Review-id: 42

Другой пример

Конечно, вы можете добавить больше "сносок" к этой заметке (мы будем придерживаться простого key: value синтаксис key: value, одно значение в строке). Например, если спустя три месяца вы узнали, что в сообщении о фиксации произошла ошибка, просто добавьте исправление в примечание:

git notes append -m "Errata: It was actually feature y."

git log:

Author: Victor Version Control <[email protected]>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes:
    Review-id: 42

    Errata: It was actually feature y.

Мы используем git notes append, чтобы легко добавить эти дополнительные данные в заметку. Вы также можете использовать git notes edit для непосредственного редактирования файла.

Конечно, поскольку Git note - это всего лишь один изменяемый файл, вы можете столкнуться с конфликтами слияния. Чтобы сделать это менее вероятным, вы можете:

  1. Придерживайтесь простых данных, как указано выше (одно значение ключа на строку).
  2. Используйте специальные стратегии слияния; см. man git-notes, раздел "Стратегии слияния заметок".

видимость

ОП спросил:

> Могу ли я сделать определенные теги невидимыми?

По умолчанию в git log отображается только одна заметка, а именно .git/refs/notes/commits. commits - это всего лишь одна заметка в пространстве имен. Может быть, вы хотите, чтобы проблемы были в их собственном пространстве имен:

git notes --ref=issues add -m "Fixes: #32"

Поскольку он хранится в .git/refs/notes/issues а не в .git/refs/notes/commits, "Fixes: # 32" не будет отображаться при запуске git log. Таким образом, вы по умолчанию сделали такие заметки невидимыми.

Если вы хотите, чтобы это было показано, передайте --notes=issues в git log:

$ git log --notes=issues
Author: Victor Version Control <[email protected]>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes (issues):
    Fixes: #32

Но теперь .git/refs/notes/commits скрыты. Это тоже можно легко включить:

$ git log --notes=issues --notes=commits
Author: Victor Version Control <[email protected]>
Date:   Tue Nov 8 21:10:25 2016 +0100

    Implement feature x

Notes (issues):
    Fixes: #32

Notes:
    Review-id: 42

    Errata: It was actually feature y.

Существуют переменные для настройки того, какие заметки показываются по умолчанию; смотрите man git-config.

Преимущества по сравнению с фиксацией сообщений

Метаданные, конечно, могут быть записаны непосредственно в сообщении коммита. († 2) Но сообщения фиксации являются неизменными, поэтому их изменение действительно означает создание совершенно нового фиксации со всеми вытекающими отсюда последствиями. Git-заметки, с другой стороны, изменчивы, поэтому вы всегда можете их пересмотреть. И каждая модификация заметки, конечно, контролируется версией. В нашем случае для .git/refs/notes/commits:

$ git log refs/notes/commits
Author: Victor Version Control <[email protected]>
commit 9f0697c6bbbc6a97ecce9834d4c9afa0d668bcad
Date:   Tue Nov 8 21:13:52 2016 +0100

    Notes added by 'git notes append'

commit b60997e49444732ed2defc8a6ca88e9e21001a1d
Author: Victor Version Control <[email protected]>
Date:   Tue Nov 8 21:10:38 2016 +0100

    Notes added by 'git notes add'

Делиться заметками

Ваши заметки не передаются по умолчанию; Вы должны сделать это явно. И по сравнению с другими ссылками, делиться заметками не очень удобно для пользователя. Мы должны использовать синтаксис refspec:

git push refs/notes/*

Выше будет толкать все ваши заметки на ваш пульт.

Кажется, что извлечение заметок немного сложнее; Вы можете сделать это, если укажете обе стороны refspec:

git fetch origin refs/notes/*:refs/notes/*

Так что это определенно не удобно. Если вы собираетесь регулярно использовать Git-notes, вы, вероятно, захотите настроить свой gitconfig так, чтобы он всегда получал примечания:

[remote "origin"]
    …
    fetch = +refs/notes/*:refs/notes/*

(Источник: https://git-scm.com/blog/2010/08/25/notes.html)

Перенос заметок на переписывание

Git имеет неудобное значение по умолчанию, что заметки не переносятся, когда коммит переписывается. Поэтому, если вы, например, перебазируете серию коммитов, заметки не будут перенесены на новые коммиты.

Переменная notes.rewrite.<command> по умолчанию имеет значение true, поэтому можно предположить, что заметки переносятся. Но проблема в том, что переменная notes.rewriteRef, которая определяет, какие заметки будут перенесены, не имеет значения по умолчанию. Чтобы установить это значение для соответствия всем заметкам, выполните следующее:

git config --global notes.rewriteRef "refs/notes/*"

Теперь все заметки будут перенесены при выполнении операций перезаписи, таких как git rebase.

Перенос заметок через почтовые патчи

Если вы используете git format-patch для форматирования изменений, отправляемых в виде электронных писем, и у вас есть некоторые метаданные, сохраненные в виде заметок Git, вы можете передать --notes в git format-patch, чтобы добавить примечания к электронному письму. проект.


† 1: "Это значение по умолчанию для git log […], если в командной строке не --oneline опция --pretty, --format или --oneline ". - man git-log, версия git 2.10.2

† 2: Одна практика/соглашение для метаданных в сообщениях фиксации, которая используется в таких проектах, как, например, Git и ядро Linux, заключается в добавлении пар ключ-значение в "трейлер" сообщения фиксации, то есть внизу. Посмотрите, например, этот коммит Линуса Торвальдса:

 mm: remove gup_flags FOLL_WRITE games from __get_user_pages()
 This is an ancient bug that was actually attempted to be fixed once
 (badly) by me eleven years ago in commit 4ceb5db9757a ("Fix
 get_user_pages() race for write access") but that was then undone due to
 problems on s390 by commit f33ea7f404e5 ("fix get_user_pages bug").

 In the meantime, the s390 situation has long been fixed, and we can now
 fix it by checking the pte_dirty() bit properly (and do it better).  The
 s390 dirty bit was implemented in abf09bed3cce ("s390/mm: implement
 software dirty bits") which made it into v3.9.  Earlier kernels will
 have to look at the page state itself.

 Also, the VM has become more scalable, and what used a purely
 theoretical race back then has become easier to trigger.

 To fix it, we introduce a new internal FOLL_COW flag to mark the "yes,
 we already did a COW" rather than play racy games with FOLL_WRITE that
 is very fundamental, and then use the pte dirty flag to validate that
 the FOLL_COW flag is still valid.

 Reported-and-tested-by: Phil "not Paul" Oester <[email protected]>
 Acked-by: Hugh Dickins <[email protected]>
 Reviewed-by: Michal Hocko <[email protected]>
 Cc: Andy Lutomirski <[email protected]>
 Cc: Kees Cook <[email protected]>
 Cc: Oleg Nesterov <[email protected]>
 Cc: Willy Tarreau <[email protected]>
 Cc: Nick Piggin <[email protected]>
 Cc: Greg Thelen <[email protected]>
 Cc: [email protected]
 Signed-off-by: Linus Torvalds <[email protected]>

Увидеть:

  • man git-interpret-trailers
  • Это вики-страница ядра, на которой перечислены различные строки трейлера (обычно пары ключ-значение), которые используются в различных проектах.