Получить хеш коммита для коммита в ветке - PullRequest
0 голосов
/ 30 мая 2019

В ветке git я храню SHA последнего коммита, используя

latest_sha=$(git log --pretty=oneline | head -1 | cut -d ' ' -f 1)

После нескольких коммитов в этой ветке, как мне получить SHA следующего коммита после latest_sha,

Скажите, если в эту ветку было сделано 5 коммитов после $ latest_sha.

Я хочу всегда получать SHA первого коммита после latest_sha.

b8eead8ba4ff375911af6
c2452680eb7731e4d36ca
da2e113ca4768f5f34730
95b98d42a6e567ed56fc2
716c4f84a855f48bee55c
6a7223a74269f925cfd9e---I need this one
e945bcfabf3fbafc85084---latest_sha
159df375376ded565bec0
d725350982626f46a8b80
56a4b6ca91d93acc8d751
de584608616b1ed99a554
3cfc15339a98bb286d5baa
6ae834bf36c90fbd81854
fa9bdebd0f814f04ee05ba
cc44c4d9ff14314c1255da
5a6145586a8fdcaa2da659
bfea8cfe121d24a0ff1525

Спасибо!

Ответы [ 3 ]

3 голосов
/ 31 мая 2019

Имя ветви Git, в некотором смысле, - это последний хэш-идентификатор. То есть, если git log branchX показывает, что вы сначала зафиксировали b8eead8ba4ff375911af6, тогда branchX - это имя, представляющее b8eead8ba4ff375911af6, и:

git show branchX

покажет такой же коммит, как:

git show b8eead8ba4ff375911af6

Если вам по какой-то причине нужен хеш-идентификатор - например, потому что вы собираетесь изменить хеш-идентификатор, на который указывает имя ветви, добавив новые коммиты, - самая простая команда для его получения: git rev-parse

hash=$(git rev-parse refs/heads/$branch)

В остальном см. ответ alfunx . Обратите внимание, что если коммиты образуют ромбовидный граф, например ::1010*

          I--J
         /    \
...--G--H      M--N   <-- branchX
         \    /
          K--L

тогда есть два коммита, которые следуют сразу за H, но либо I, либо K не являются предками друг друга, они связаны только тем, что оба являются потомками H и предки (в данном случае дедушки и бабушки) слияния совершают M. Используя git rev-list --ancestry-path ^<anything-identifying-H> <anything-identifying-branchX>, вы получите список коммитов I, J, K, L, M и N. Листинг начнется с N и вернется к M в качестве его второй записи, но в этот момент Git теперь имеет выбор: перечислять J или L. Именно здесь вступают в силу выбранные вами варианты сортировки. Сортировка по умолчанию - хронологическая по дате и времени коммиттера.

Перечислив либо J, либо L, Git теперь может перечислить родителя того, какой коммит он перечислил, или оставшегося коммита на другом форке истории. Git перечислит один из них. Если он решил сначала перечислить J, затем I, теперь он должен перечислить L, а затем K в этом порядке; если он сначала выбрал список L, затем K, теперь он должен отображать I, а затем J в этом порядке. Но он может также перечислить их в порядке J, L, K, I, например; или J, L, I, K. Добавление --topo-order ограничивает git rev-list, чтобы избежать чередования коммитов с двух сторон.

Порядок линеаризации в сложных графах обычно проблематичен: не существует единого решения, которое бы обрабатывало все случаи. Вот почему git rev-list предлагает несколько вариантов сортировки.

2 голосов
/ 30 мая 2019

Вы можете сделать это с помощью rev-list:

git rev-list --ancestry-path HEAD ^${latest_sha} | tail -n1

rev-list перечисляет все достижимые коммиты в обратном хронологическом порядке для данных ветвей / коммитов. Символ каретки (^) здесь означает «не», что позволяет Git исключать все достижимые коммиты, начиная с данного коммита.

Конкретно это означает: включите все коммиты, достижимые с HEAD, исключите все коммиты, достижимые с ${latest_sha}, а затем возьмите самый старый, используя tail.

Редактировать: Добавить --ancestry-path, чтобы убедиться, что используются только те коммиты, которые находятся на пути прямого предка между указанными коммитами (как упомянуто @jthill).

0 голосов
/ 30 мая 2019

git logs имеют родительское поле коммита, так что вы можете сделать что-то вроде

git log --pretty=format:"%P %H" | awk '$1 == "<YOUR_HASH>" {print $2}'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...