Хранить информацию в ветке (метаданные) о том, с какой точки она расходится с «родительской» веткой - PullRequest
0 голосов
/ 01 сентября 2018

Скажите, у меня есть это:

latest_commit=`git rev-parse HEAD`
git checkout -b "foo_$latest_commit"
git reset --soft "origin/dev"

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

В конце концов, что я пытаюсь сделать? Я собираюсь объединить foo_ $ latest_commit с веткой интеграции после сжатия коммитов с помощью git reset --soft. Позже я хочу смело удалять как первую, так и вторую ветку. Я могу безопасно удалить первую ветку, если конец первой ветви совпадает с идентификатором фиксации в имени второй ветви.

1 Ответ

0 голосов
/ 01 сентября 2018

... есть ли способ хранить метаданные где-нибудь во 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».

(То, что вы можете получить с помощью хитрости метаданных, - это автоматически запомнить подходящее имя, но на практике оказывается, что большинству людей это, как правило, не нужно. Для вашего конкретного использования это может быть хорошим вещь, хотя. Я вставил этот раздел, потому что я уверен, что в будущем другие люди найдут ваш вопрос и этот ответ и подумают, что это умный способ запомнить "базовую ветвь" для каждой производной ветки. Что это, но это не такая умная вещь.)

...