Каковы плюсы и минусы пользовательских предметов и ссылок?

Допустим, я хочу написать небольшой помощник, который позволяет добавлять некоторые метаданные в хранилище таким образом, чтобы он мог распространяться к клонам через refs, Простой пример (прототип клона git-notes, который даже не прикрепляет примечания к любому другому объекту git):

hash=$(echo "Just a comment" | git hash-object -w --stdin)
git rev-update refs/comments/just $hash

т.е. я создаю blob с хешем hash и относиться к этому как refs/comments/just так git fsck --unreachable не буду жаловаться на это и git gc никогда prune предмет.

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

Например, несколько сообщений на SE касались пользователей, которым необходимо восстанавливаться после дублирования tree записей. Таким образом, одно "не", следовательно, "не создавать tree с повторяющимися записями ". Другой пример" убедитесь, что ваши объекты достижимы, поэтому git prune не буду их удалять ". Что еще?

Могу ли я создать собственный тип объекта? Использовать "недействительные" файловые режимы для больших двоичных объектов в деревьях? Где я могу найти обзор? Или я должен проверить git-fsck источник вручную, чтобы увидеть, что является ошибками (а какие игнорируются)?

1 ответ

что можно и что нельзя делать с пользовательскими объектами и ссылками?

Действия:

  • Сделайте резервную копию вашего репозитория . Прежде чем вносить существенные изменения во внутреннюю структуру репозитория, создайте резервную копию. Я рекомендовал перед использованием git bundle create /tmp/foo-all --all.

  • Используйте отдельное пространство имен . Если вы вводите собственные ссылки, попробуйте использовать отдельное пространство имен (например,refs/comments/ в вашем примере), чтобы избежать конфликтов с обычными именами ссылок Git .

  • Обеспечьте доступность объектов : ваши пользовательские объекты всегда должны быть доступны по какой-либо ссылке, чтобы избежать случайного сокращения git gcили более поздний git maintenance.

  • Тестирование в отдельном репозитории . Прежде чем применять настройки к основному или рабочему репозиторию, протестируйте его в отдельном или клонированном репозитории, чтобы подтвердить свои предположения и убедиться в отсутствии неожиданных последствий.

  • Придерживайтесь типов объектов : придерживайтесь четырех основных типов объектов (блоб, дерево, фиксация и тег) для максимальной совместимости. Если вы пытаетесь сохранить пользовательские данные, обычно имеет смысл сохранить их как большой двоичный объект, а затем ссылаться на них из тега или фиксации.

Не следует:

  • Избегайте повторяющихся записей дерева . Как вы заметили, объекты дерева не должны содержать повторяющиеся записи. Это может привести к неожиданному поведению.

  • Не используйте недопустимые файловые режимы . Хотя может показаться заманчивым использовать собственные файловые режимы для больших двоичных объектов в деревьях, это может вызвать проблемы. Придерживайтесь признанных режимов, подробно описанных здесь (040000для подкаталога (дерева),100644для файла (блоба),100755для исполняемого файла и120000для символической ссылки).

  • Избегайте создания пользовательских типов объектов : Git распознает четыре основных типа объектов (блоб, дерево, фиксация и тег). Введение пользовательских типов объектов, скорее всего, сломает внутренние механизмы и инструменты Git, которые ожидают только эти четыре.

  • Не изменяйте существующие объекты . Целостность Git зависит от неизменяемости объектов. После создания объекта его ни в коем случае нельзя изменять. Если необходимы изменения, создайте новый объект и соответствующим образом обновите ссылки.

  • Избегайте несоответствий с SHA-1: хеш SHA-1 является неотъемлемой частью идентификации и проверки объекта в Git. Любая пользовательская операция, которая может привести к несоответствию между содержимым объекта и его хешем, категорически запрещена.


user1290731 спросил в комментариях:

какая конкретная разница между «заметками, которые даже не прикрепляют заметки к какому-либо другому объекту git» и просто обычной боковой веткой (с собственным корнем)?

  • Заметки Git — это способ добавления произвольных метаданных к объектам без изменения самих объектов. Обычно это означает добавление примечаний к коммитам. Заметки хранятся в отдельных ссылках, обычно в папкеrefs/notes/, но они «прикрепляются» к другому объекту (например, к коммиту), ссылаясь на хеш этого объекта.

  • Боковая ветвь — это обычная ветвь, но, возможно, используемая для целей, отличных от основных ветвей. У него есть собственная история коммитов и дерево. Он хранится подrefs/heads/как и любая другая ветка.

Следовательно, рекомендация jthill: создайте "mynotes"ветвь и используй git worktree(то, что я представил здесь).
Это создаст отдельное рабочее пространство для этих метаданных, полностью изолированное от вашей основной работы.

Другие вопросы по тегам