Каковы плюсы и минусы пользовательских предметов и ссылок?
Допустим, я хочу написать небольшой помощник, который позволяет добавлять некоторые метаданные в хранилище таким образом, чтобы он мог распространяться к клонам через 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
(то, что я представил здесь).
Это создаст отдельное рабочее пространство для этих метаданных, полностью изолированное от вашей основной работы.