Ответ 1
Прежде чем вы сможете ответить на вопрос о том, какие ветки содержат эквивалентную фиксацию, вы должны определить, "какие коммиты эквивалентны". После этого вы просто используете git branch --contains
для каждого из коммитов.
К сожалению, нет 100% надежного способа определения эквивалентных коммитов.
Самый надежный метод - проверить идентификатор патча набора изменений, введенного коммитом. Это то, на что полагаются git cherry
, git log --cherry
и git log --cherry-mark
. Внутри они все называют git patch-id
. Идентификатор патча - это только SHA1 нормализованного разброса изменений. Любая фиксация, которая вводит идентичные изменения, будет иметь один и тот же идентификатор патча. Кроме того, любая фиксация, которая вводит в основном идентичные изменения, которые отличаются только пробелом или номером строки, в котором они применяются в файле, будет иметь одинаковый идентификатор патча. Если две коммиты имеют одинаковый идентификатор патча, почти гарантировано, что они эквивалентны - вы практически никогда не получите ложный результат через идентификатор патча. Ложные негативы часто возникают. Каждый раз, когда вы выполняете git cherry-pick
и вам приходится вручную разрешать конфликты слияния, вы, вероятно, вносили различия в набор изменений. Даже изменение 1 символа приведет к созданию другого идентификатора патча.
Проверка идентификатора патча требует написания сценариев, как советует Chronial. Сначала вычислите патч-идентификатор оригинала с чем-то вроде
(примечание - скрипты, которые не тестировались, должны быть достаточно близки к работе)
origCommitPatchId=$(git diff ORIG_COMMIT^! | git patch-id | awk '{print $1}')
Теперь вам нужно будет выполнить поиск по всем другим записям в вашей истории и рассчитать идентификаторы патчей для них и посмотреть, одинаково ли они из них.
for rev in $(git rev-list --all)
do
testPatchId=$(git diff ${rev}^1..${rev} | git patch-id | awk '{print $1}')
if [ "${origCommitPatchId}" = "${testPatchId}" ]; then
echo "${rev}"
fi
done
Теперь у вас есть список SHA, и вы можете передать их на git branch -a --contains
Что делать, если вышеупомянутое не работает для вас, хотя из-за конфликтов слияния?
Ну, есть еще несколько вещей, которые вы можете попробовать. Обычно, когда вы выбираете фиксацию, вы сохраняете исходное имя автора, адрес электронной почты и поля даты в фиксации. Таким образом, вы получите новый коммит, но информация об авторстве будет идентичной.
Итак, вы можете получить эту информацию с вашего оригинального коммита с помощью
git log -1 --pretty="%an %ae %ad" ORIG_COMMIT
Затем, как и прежде, вам придется пройти через каждую фиксацию в своей истории, распечатать эту же информацию и сравнить ее. Это может дать вам дополнительные совпадения.
Вы также можете использовать git log --grep=ORIG_COMMIT
, который найдет любые коммиты, которые ссылаются на ORIG_COMMIT в сообщении фиксации.
Если ни одна из этих работ не может попытаться найти конкретную строку, которая была введена с помощью кирки, или может git log --grep
для чего-то еще, что могло быть уникальным в сообщении фиксации.
Если это все звучит сложно, ну, это так. Вот почему я говорю людям избегать использования вишневого салата, когда это возможно. git branch --contains
невероятно ценна и проста в использовании и на 100% надежна. Ни одно из других решений даже не приближается.