В основном, способы сделать это могут показаться неэффективными, потому что это не операция, которая упрощается с помощью задействованных структур данных. По сути, вам приходится перебирать все ссылки, особенно если вы хотите все ветви, которые указывают на фиксацию. Команды, которые упрощают это, делают это, давая вам синтаксис для выражения того, что вы хотите, но все же они должны выполнять итерации по ссылкам. Хорошая новость в том, что это звучит хуже, чем есть.
Обратите внимание, что у вашего второго метода есть еще одна ловушка: он попытается придумать какое-то имя для коммита, даже если на него не указывает ни одна ветвь. Так master~1
, например, является допустимым выводом для этой команды. Он также может возвращать undefined
в случае, когда коммит недоступен, но я думаю, что это маловероятный вариант использования.
Звучит так, будто вы хотите, чтобы ветки указывали непосредственно на коммит (в отличие от каждой ветки, которая может достичь коммит), и это помогает, поскольку это устраняет потенциальную необходимость обхода истории каждого реф.
Итак, в любом случае ... да, ваш первый метод - это путь, с парой возможных улучшений.
Опция --points-at
позаботится о фильтрации для вас (если вы не используете более старую версию git).
Опция --format
может помочь с извлечением имени ветки (хотя, насколько я знаю, это не даст вам 100% пути, потому что вы, вероятно, хотите удалить префикс refs/heads/
).
Так что это может собраться как
git for-each-ref --points-at $sha1 --format='%(refname)` refs/heads | cut -c12-