Указывает, является ли фиксация Git фиксацией слияния / возврата
-
26-09-2019 - |
Вопрос
Я пишу скрипт, который требует проверки того, является ли конкретный коммит коммитом слияния / возврата или нет, и мне интересно, есть ли для этого трюк git.
То, что я придумал до сих пор (и я определенно не хочу зависеть здесь от сообщения о фиксации), - это проверить HASH^2
и посмотрите, если я не получу сообщение об ошибке, есть ли способ получше?
Решение
Выяснить, является ли что-то слиянием, несложно.Это все коммиты с более чем одним родителем.Чтобы проверить это, вы можете сделать, например
$ git cat-file -p $commit_id
Если в выходных данных есть более одной `родительской" строки, значит, вы обнаружили слияние.
Для ревертов это не так просто.Как правило, реверты - это просто обычные коммиты, которые случайно применяют разницу предыдущего коммита в обратном порядке, эффективно удаляя изменения, внесенные коммитом.В остальном здесь нет ничего особенного.
Если возврат был создан с помощью git revert $commit
, затем git обычно генерирует сообщение о фиксации с указанием возврата и того, какой коммит был отменен.Однако вполне возможно выполнить возврат другими способами или просто изменить сообщение о фиксации коммита, сгенерированного git revert
.
Поиск этих сгенерированных сообщений о возврате фиксации уже может быть достаточно хорошей эвристикой для того, чего вы пытаетесь достичь.Если нет, вам придется фактически просмотреть другие коммиты, сравнивая их различия друг с другом, поиск одного - это точная обратная операция другого.Но даже это не является хорошим решением.Достаточно часто возвраты немного отличаются от просто обратной фиксации, которую они возвращают, например, для адаптации к изменениям кода, которые произошли между фиксацией и возвратом.
Другие советы
Следующая инструкция будет выбросить Только родительские хэши. Менее фильтрация необходима ...
git show --no-patch --format="%P" <commit hash>
Ответ с использованием git cat-file
использует Git "сантехника" Команда, которая, как правило, лучше для создания сценариев, поскольку формат выходных данных вряд ли изменяется. Те, которые используют 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-Rev-list с конкретным Гитруризды запрос ${sha}~1..${sha}
Таким образом, что печатает второй родитель SHA, если он существует или ничего, если оно нет, то есть точное определение объединения.
Конкретно, SHA~1..SHA
означает Включите коммиты, которые доступны от SHA, но исключают те, которые являются доступными для SHA ~ 1, что является первым родителем SHA.
Результаты хранятся в $ msha и проверены на пустоту с помощью bash [ -z "$msha" ]
Неспособность (возвращение 1), если пустое или прохождение (возвращение 0), если не пусто.
Один из способов тестирования для слияния Commit:
$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT
Что касается Git Revert, я согласен с @rafl. что самый реалистичный подход - искать ревертную сообщение Boeterplate в сообщении Commit; Если кто-то изменил его, обнаружение так будет очень вовлечено.
Легкий способ проверить для слияния Commit:
git show --summary HEAD | grep -q ^Merge:
Это вернется 0 для слияния коммитов, 1 для не слияния. Замените голову нужным обязательством, чтобы проверить.
Пример использования:
if git show --summary some-branch | grep -q ^Merge: ; then
echo "some-branch is a merge"
fi
Еще один способ найти родителей фиксации:
git show -s --pretty=%p <commit>
Использовать %P
для полного хеша. Это отпечатывает, сколько родителей HEAD
имеет:
git show -s --pretty=%p HEAD | wc -w