С Git, как я могу определить, является ли какой-либо фиксатор в моей ветке потомком другого коммита?
Как я могу определить, является ли кто-то одним из потомков другого коммита?
Ответ 1
Если вы хотите проверить это программно (например, в скрипте), вы можете проверить, равен ли git merge-base A B
git rev-parse --verify A
(тогда A достижим из B), или если это git rev-parse --verify B
(тогда B достижим из A), Здесь git rev-parse
необходим для преобразования имени коммита в SHA-1/идентификатор фиксации.
Использование git rev-list
, как в VonC-ответе также возможно.
Изменить: в современном Git есть явная поддержка этого запроса в виде git merge-base --is-ancestor
.
Если один из коммитов, о котором вы спрашиваете, является веткой, тогда git branch --contains <commit>
или git branch --merged <commit>
может быть лучшим непрограммным решением.
Ответ 2
От Git 1.8.0, это поддерживается как опция merge-base
:
git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>
На странице man:
- это-предок
Проверьте, является ли первый предком второго, и выйдите со статусом 0, если true, или со статусом 1, если нет. Ошибки сигнализируется ненулевым статусом, который не равен 1.
Например:
git merge-base --is-ancestor origin/master master; echo $?
Ответ 3
Этот вид операций основан на понятии диапазона ревизий, подробно описанном в вопросе SO: "Разница в 'git log origin/master vs' git log origin/master..".
git rev-list
должен иметь возможность переходить от коммита до другого, если он доступен.
Поэтому я бы попробовал:
git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20
(Граничные коммиты начинаются с -
)
Если последний отображаемый коммит совпадает с первым коммитом в команде git rev-list
, то это коммит, достижимый при втором коммите.
Если первый коммит недоступен со второго, git rev-list
ничего не должен возвращать.
git rev-list --boundary A..B
закончится к A
, если A
достижим из B
.
Это так же, как:
git rev-list --boundary B --not A
с B
положительной ссылкой и A
отрицательной ссылкой.
Он начинается с B
и идет назад по графику, пока не встретит ревизию, доступную из A
.
Я бы сказал, что если A
напрямую доступен из B
, он встретится (и отобразится из-за опции --boundary
) самого A
.
Ответ 4
Другим способом было бы использовать git log и grep.
git log --pretty=format:%H abc123 | grep def456
Это приведет к созданию одной строки вывода, если commit def456 является предком commit abc123, иначе выход не будет выполнен.
Обычно вы можете уйти с аргументом "--pretty", но это не так, если вы хотите убедиться, что вы просматриваете только фактические хэши-коммиты, а не комментарии к журналу и т.д.
Ответ 5
fooobar.com/questions/68814/... упоминает об этом, теперь, чтобы сделать его более дружественным к человеку:
git-is-ancestor() (
if git merge-base --is-ancestor "$1" "$2"; then
echo 'ancestor'
elif git merge-base --is-ancestor "$2" "$1"; then
echo 'descendant'
else
echo 'unrelated'
fi
)
alias giia='git-is-ancestor'
Ответ 6
git show-branch branch-sha1 commit-sha1
Где:
- branch-sha1: sha1 в вашей ветке, которую вы хотите проверить
- commit-sha1: sha1 фиксации, которую вы хотите проверить,
Ответ 7
Настройте ответ на itub, если вам нужно сделать это для всех тегов в репозитории:
for i in `git tag` ; do echo -ne $i "\t" ; git log --pretty=format:%H $i | (grep <commit to find> || echo ""); done