Если требуется выполнить Git commit - слияние/возврат
Я пишу script, который требует проверки того, является ли конкретная фиксация фиксацией Merge/Revert или нет, и мне интересно, есть ли для этого трюк git.
То, что я придумал до сих пор (и я определенно не хочу зависеть от сообщения о фиксации здесь), - это проверить HASH^2
и посмотреть, не получится ли я ошибка, есть ли лучший способ?
Ответы
Ответ 1
Выяснить, легко ли что-то слияние. То, что все совершает с несколькими родителями. Чтобы проверить это, вы можете сделать, например
$ git cat-file -p $commit_id
Если на выходе имеется более одной "родительской" строки, вы обнаружили слияние.
Для возврата это не так просто. Как правило, реверты - это просто нормальные коммиты, которые, случается, применяют разницу предыдущего фиксации в обратном направлении, эффективно удаляя внесенные изменения. В противном случае это не так.
Если реверс был создан с помощью git revert $commit
, то git обычно генерирует сообщение сообщения фиксации, которое возвращается и что оно завершает. Однако вполне возможно сделать реверты другими способами или просто изменить сообщение фиксации коммита, сгенерированного git revert
.
Поиск этих генерируемых сообщений revert commit уже может быть достаточно эвристическим для того, чего вы пытаетесь достичь. Если нет, вам придется фактически просмотреть другие коммиты, сравнивая их различия друг с другом, глядя на то, что это точная обратная операция другого. Но даже это не очень хорошее решение. Зачастую реверты немного отличаются от того, что происходит в обратном направлении, которое они возвращают, например, для размещения изменений кода, которые произошли между фиксацией и возвратом.
Ответ 2
Следующая команда выгрузит только родительские хэши. Требуется меньше фильтрации...
git show --no-patch --format="%P" <commit hash>
Ответ 3
Ответ с использованием 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 верхнего уровня.
В этом коде используется git-rev-list с определенным gitrevisions ${sha}~1..${sha}
таким образом, который печатает второй родительский SHA, если он существует, или ничего, если он отсутствует, что является точным определением фиксации слияния.
В частности, SHA~1..SHA
означает включение коммитов, которые доступны из SHA, но исключают те, которые достигают SHA ~ 1, который является первым родителем SHA.
Результаты сохраняются в $msha и проверяются на пустоту с использованием bash [ -z "$msha" ]
failing (return 1), если он пуст, или передают (возвращают 0), если не пуст.
Ответ 4
Один способ проверить фиксацию слияния:
$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT
Что касается git revert commits, я согласен с @rafl, что наиболее реалистичным подходом является поиск возвращаемого шаблона сообщения в сообщении фиксации; если кто-то изменил это, обнаружение будет очень привлекательным.
Ответ 5
Простой способ проверки слияния:
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
Ответ 6
Еще один способ найти родителей:
git show -s --pretty=%p <commit>
Используйте %P
для полного хэша. Это печатает, сколько родителей HEAD
имеет:
git show -s --pretty=%p HEAD | wc -w