Git: Получить все имена веток для данной ревизии - PullRequest
0 голосов
/ 07 мая 2018

Учитывая хеш коммита, каков наилучший способ получить все имена веток, которые указывают на этот коммит?

Вариант 1: грубая сила. Используйте git for-each-ref refs/heads для получения всех ветвей, фильтрации при фиксации и извлечения имен ветвей.

Вариант 2: используйте git name-rev --name-only. Однако это дает только одну ветвь (если несколько ветвей указывают на один и тот же коммит).

В конечном итоге я действительно хочу отсортированный по топам список имен веток между двумя коммитами (где коммиты с несколькими ветвями будут иметь несколько записей). Кажется, что git, вероятно, может делать то, что я хочу, и я просто не могу найти правильную команду.

РЕДАКТИРОВАТЬ: Обратите внимание, что я не спрашиваю, какие ветви содержат данный коммит. Я хочу знать, какие ветви имеют этот коммит в качестве головы.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

В основном, способы сделать это могут показаться неэффективными, потому что это не операция, которая упрощается с помощью задействованных структур данных. По сути, вам приходится перебирать все ссылки, особенно если вы хотите все ветви, которые указывают на фиксацию. Команды, которые упрощают это, делают это, давая вам синтаксис для выражения того, что вы хотите, но все же они должны выполнять итерации по ссылкам. Хорошая новость в том, что это звучит хуже, чем есть.

Обратите внимание, что у вашего второго метода есть еще одна ловушка: он попытается придумать какое-то имя для коммита, даже если на него не указывает ни одна ветвь. Так master~1, например, является допустимым выводом для этой команды. Он также может возвращать undefined в случае, когда коммит недоступен, но я думаю, что это маловероятный вариант использования.

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

Итак, в любом случае ... да, ваш первый метод - это путь, с парой возможных улучшений.

Опция --points-at позаботится о фильтрации для вас (если вы не используете более старую версию git).

Опция --format может помочь с извлечением имени ветки (хотя, насколько я знаю, это не даст вам 100% пути, потому что вы, вероятно, хотите удалить префикс refs/heads/).

Так что это может собраться как

git for-each-ref --points-at $sha1 --format='%(refname)` refs/heads | cut -c12-
0 голосов
/ 07 мая 2018

Если ваш Git достаточно новый, git for-each-ref --points-at делает именно то, что вы хотите (примените к refs/heads пространству имен и добавьте любое форматирование, которое вам нравится).

Опция --points-at была новой в Git 2.7.0. В более старых версиях вы все равно должны использовать git for-each-ref, но вам нужно будет отфильтровать только тех, чей ID хеша является желаемым.


Стоит отметить, для вашей конечной цели: git log --decorate добавит ссылочные декорации для идентификаторов фиксации, поэтому вы можете использовать git log --decorate --format='%H %d'. Добавьте --topo-order и --ancestry-path start..end, чтобы получить топо-отсортированные коммиты, которые включают end, но исключают start и являются потомками start и предков end. Пропустите --ancestry-path, если вы не хотите требовать "потомков" части. (Рассмотрите --boundary, если вы хотите включить стартовый коммит, но будьте осторожны, --boundary иногда выбирает слишком много коммитов.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...