... есть ли способ хранить метаданные где-нибудь во 2-й ветке ...
Не напрямую, нет.
Помните, что каждая ветвь name является просто (перемещаемым) указателем на коммит со специальным свойством, которое, если вы используете git checkout
, чтобы "включить" ветвь, git commit
автоматически перемещает указатель. Различные другие команды готовы переместить его различными способами: например, git merge --ff-only
переместит текущее имя ветви в ускоренном порядке, в то время как git reset
переместит его произвольно.
Итак: где может хранить метаданные? Это немного сложно.
Git состоит из двух основных баз данных: само хранилище является хранилищем значений ключей с хэш-идентификаторами в качестве ключей и объектами хранилища (BLOB-объектами, деревьями, коммитами и аннотированными тегами) в качестве значений. Между тем ссылки - имена ветвей в refs/heads/*
, имена тегов в refs/tags/*
, тайник в refs/stash
и т. Д. - являются хранилищем значений ключей с несколькими немного странными ограничениями на ключи (см. git check-ref-format
для большинство из них), чьи значения являются хэш-идентификаторами.
Поскольку ваша цель - (я думаю) связать имя ветви с двумя различными идентификаторами хеша, один из очевидных подходов - создать собственное пространство имен в refs
. Допустим, мы выбрали, например, refs/bases/
. Для ветви с именем B (например, полное имя refs/heads/B
) вам просто нужно создать refs/bases/B
. Единственное, что вы можете сохранить в refs/bases/B
, это хеш-идентификатор, но это именно то, что вы хотите сохранить, так что все готово.
Если вы хотите сохранить более или просто что-то, кроме простого хеш-идентификатора, например, если вы хотите сохранить другое имя , вам понадобится какой-то объект данных. Вы можете выбрать любой из четырех типов объектов, но два из них строго ограничены: дерево или коммит должны быть правильно отформатированы. Один из них имеет слабые ограничения: объект аннотированного тега должен содержать хэш-идентификатор другого объекта - цели аннотированного тега - и может затем содержать произвольный текст. Последний, blob , является неограниченным, поскольку может содержать любой произвольный текст.
Чтобы создать аннотированный объект тега, используйте git mktag
. Информацию о необходимом формате тегов см. В документации.
Чтобы создать BLOB-объект, используйте git hash-object -w
, возможно, с --stdin
; см. его документацию.
Оба выводят хеш-идентификатор, который затем можно установить в качестве хеш-идентификатора для хранения в refs/bases/B
или refs/xyz-meta/B
или в любом другом пространстве имен, которое вы выберете.
Последнее замечание
Для большинства случаев использования Git способ работы заключается не в сохранении имени базовой ветви или хеш-кода базовой фиксации. Вместо этого используйте set subtraction , чтобы запросить достижимый коммит, в виде:
- Все коммиты достижимы от имени T (для подсказки); но
- Исключая все коммиты, достижимые из имени S (для остановки).
Это именно то, что git rebase
делает с передаваемым им аргументом, например: когда вы запускаете git checkout feature; git rebase develop
, Git перечисляет все коммиты , достижимые из feature
, минус все коммиты достижимы с develop
. В Git это так часто встречается, что он имеет синтаксис git rev-list
: develop..feature
означает feature ^develop
, что означает «коммиты, достижимые с feature
, исключая коммиты, достижимые с develop
».
(То, что вы можете получить с помощью хитрости метаданных, - это автоматически запомнить подходящее имя, но на практике оказывается, что большинству людей это, как правило, не нужно. Для вашего конкретного использования это может быть хорошим вещь, хотя. Я вставил этот раздел, потому что я уверен, что в будущем другие люди найдут ваш вопрос и этот ответ и подумают, что это умный способ запомнить "базовую ветвь" для каждой производной ветки. Что это, но это не такая умная вещь.)