Это правда, что имена тегов должны быть уникальными, но есть бесконечное число уникальных имен тегов начиная сmark/
, такие как mark/1
, mark/2
и так далее. Или вы можете использовать имена ссылок, которые не находятся в refs/tags/
; или вы могли бы использовать «ноты» GIT, хотя это легче обнаружить ли тег или другая ссылка, является предком один совершить и потомок другого:
highmark=$(git for-each-ref --format='%(refname)' refs/marks | wc -l)
nextmark=$((highmark + 1)
git update-ref refs/marks/m$nextmark HEAD
(это предполагает, что вы никогда не удалять, с git update-ref -d
, любой из этих меток - если вы выполняете вычисление «высокая отметка», нужно найти наивысшее существующее число вместо простого подсчета). Для того, чтобы проверить, если знак $ N является «между» тегом T1 и ГЛАВОЙ:
if git merge-base --is-ancestor T1 refs/marks/m$N &&
git merge-base --is-ancestor refs/marks/m$N HEAD; then
... mark N is at or beyond tag T1 and at or before HEAD ...
else
... mark N is not between those two points (inclusive) ...
fi
В качестве альтернативы, вы можете хранить, или вне хранилища, и если внутри хранилища, в простом шарикообразном блоб является Git и внутренний формат для необработанных файлов - файл, который просто содержит хеш-идентификаторы всех «отмеченных» коммитов. Сам файл может быть сохранен в тегированном или иным образом связанном коммите, который может, но не обязательно, в любой ветви; или вы можете пометить сам blob. Например:
git show marks > /tmp/all-marks # extract existing marks
git rev-parse HEAD >> /tmp/all-marks # add a new mark
git tag -f marks $(git hash-object -w --stdin < /tmp/all-marks)
Если вы храните блобы под коммите, вы можете сохранить историю знаков, сделав новые коммиты для каждого нового обновленного «отмечен ИД» файл. Это в некотором роде аналогично способу работы git notes
, но вместо того, чтобы записывать файлы, имена которых являются идентификаторами коммитов, вы просто пишете файл с именем «метки» (хранящийся через дерево, которое затем указывает на фиксацию, что ссылка на метку - это такой тег, как refs/tags/marks
, как в приведенном выше примере тега, или ссылка, как refs/marks
, например, ссылки на серии m
, но только с использованием одной ссылки). Поскольку каждый фиксатор имеет родительский указатель, вы можете сохранить предыдущую фиксацию, которая сохраняет предыдущее дерево, которое сохраняет предыдущий файл blob/marks, и вы можете даже запустить git log
на этих коммитах, чтобы узнать, кто обновил метки, и т.д.
Ну, конечное, но ограничены только дисковым пространством и шаблонами имен. Предлагаемый здесь шаблон, считая decimally в именах файлов в одном пространстве имен, может рассчитываться только до 10 в типичных файловых системах Unix-ish с их 255-байтовым пределом длины имени компонента. Практически говоря, вы, вероятно, не захотите пройти много лет до того, как сделать иерархические имена, например, refs/marks/123/456/789
, после того, как вы перейдете к нескольким миллионам отмеченных коммитов.
операционка также налагают максимальную длину пути, но вы бы исчерпать совершать идентификаторы задолго до того, вы попали те: 2 всего 1 461 501 637 330 902 918 203 684 832 716 283 019 655 932 542 976, или около 1.462 sexdecillion в номенклатуре short scale. Хуже того, ваш шанс столкнуться с хешем становится слишком высоким после нескольких квинтиллионных объектов, так что нам нужно рассчитывать только на 10 .
Но основная функция тега в git - это отметить основные версии (точка выпуска). И аннотированный тег почти такой же, как и фиксация. –