Указание, является ли коммит Git коммитом Merge / Revert - PullRequest
33 голосов
/ 29 сентября 2010

Я пишу скрипт, который требует проверки того, является ли конкретный коммит коммитом слияния / возврата или нет, и мне интересно, есть ли для этого мерзавец.

Что я придумала до сих пор(и я определенно не хочу зависеть от сообщения о фиксации здесь), чтобы проверить HASH^2 и посмотреть, если я не получаю ошибку, есть ли лучший способ?

Ответы [ 6 ]

42 голосов
/ 29 сентября 2010

Выяснить, является ли что-то слиянием, легко. Это все совершает с более чем одним родителем. Чтобы проверить это, вы можете сделать, например,

$ git cat-file -p $commit_id

Если в выводе есть более одной «родительской» строки, вы нашли слияние.

Для возврата это не так просто. Обычно возвраты - это просто обычные коммиты, которые применяют разность предыдущего коммита в обратном порядке, эффективно удаляя внесенные изменения. Там нет ничего особенного.

Если реверт был создан с помощью git revert $commit, то git обычно генерирует сообщение о коммите, указывающее реверт и какой коммит он отменил. Тем не менее, вполне возможно сделать возврат другими способами или просто изменить сообщение коммита коммита, сгенерированного git revert.

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

16 голосов
/ 24 апреля 2013

Следующая инструкция выведет только родительские хеши. Требуется меньше фильтрации ...

git show --no-patch --format="%P" <commit hash>

9 голосов
/ 19 декабря 2012

В ответе git cat-file используется команда git "plumbing" , которая, как правило, лучше подходит для построения сценариев, поскольку выходной формат вряд ли изменится.Те, которые используют git show и git rev-parse, могут нуждаться в изменении со временем, так как они используют команды фарфор .

Функция bash, которую я использовал длядолгое время использует git rev-list:

gitismerge () {
    local sha="$1"
    msha=$(git rev-list -1 --merges ${sha}~1..${sha})
    [ -z "$msha" ] && return 1
    return 0
}

Список команд фарфора / сантехники можно найти в документации для команды верхнего уровня git .

Thisкод использует git-rev-list с определенным gitrevisions запросом ${sha}~1..${sha} способом, который печатает второго родителя SHA, если он существует, или ничего, если его нет, что являетсяточное определение коммита слияния.

В частности, SHA~1..SHA означает, что включает коммиты, которые достижимы из SHA, но исключают коммиты, которые достижимы SHA ~ 1, который является первым родителем SHA .

Результаты сохраняются в $ msha и проверяются на пустоту с помощью bash [ -z "$msha" ], который завершается с ошибкой (возвращает 1), если она пуста, или передачей (возвращается 0), если она не пуста.

2 голосов
/ 05 марта 2013

Один из способов проверить коммит слияния:

$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT

Что касается коммитов git revert, я согласен с @ rafl , что наиболее реалистичным подходом является поиск сообщения возвраташаблон в сообщении фиксации;если бы кто-то изменил это, обнаружение было бы очень сложным.

1 голос
/ 25 января 2016

Простой способ проверить коммит слияния:

git show --summary HEAD | grep -q ^Merge:

Это вернет 0 для коммитов слияния, 1 для коммитов без слияния.Замените HEAD желаемым коммитом для тестирования.

Пример использования:

if git show --summary some-branch | grep -q ^Merge: ; then
    echo "some-branch is a merge"
fi
0 голосов
/ 07 декабря 2018

Еще один способ найти родителей комита:

git show -s --pretty=%p <commit>

Используйте %P для полного хэша. Это печатает, сколько родителей HEAD имеет:

git show -s --pretty=%p HEAD | wc -w
...