Подтвердить что ты не робот

Как определить конфликтующие коммиты с помощью хэша во время git rebase?

Когда я сталкиваюсь с конфликтом слияния с помощью git rebase, как я могу определить источник конфликта с точки зрения коммитов, а не только различий в файлах?

Я уже знаю, как сделать (базовое) использование git mergetool или git add до git rebase --continue, но иногда различий между файлами просто недостаточно: я хочу увидеть журнал фиксации и diff commit который просто не применим к рабочему дереву.

Я читал в других вопросах, что git log --merge будет показывать родительские коммиты, если бы я использовал git merge. Я пробовал это в любом случае, когда я столкнулся с конфликтом и получил сообщение fatal: --merge without MERGE_HEAD?.

Как я могу идентифицировать проблемную фиксацию?

4b9b3361

Ответ 1

Краткий ответ

Если он говорит

Patch failed at 0001 commit message for F

Затем запустите

$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001

Чтобы получить SHA ad1c77 неудачной фиксации, а затем используйте git show ad1c77, чтобы посмотреть на нее.

Длинный ответ

Начнем с этого дерева:

A---B---C---D
     \
      E---F---G

$ git checkout G
$ git rebase D

Когда возникает конфликт с пересылкой, это конфликт между

  • восходящие изменения (C--D) от общего предка (B) PLUS уже измененные изменения и уже разрешенный конфликт (E') по сравнению с
  • патч следующего фиксации (F)

Посмотрим, что получится:

1) A---B---C---D---E'          <- E patched and committed successfully as E'
2) A---B---C---D---E'---       <- failed to patch F onto E'

Здесь появляется сообщение об ошибке:

First, rewinding head to replay your work on top of it...
Applying: commit message for F
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
Failed to merge in the changes.
Patch failed at 0001 commit message for F

Во-первых, вы можете видеть, что это было F, потому что появляется сообщение фиксации. Однако, если ваши сообщения фиксации выглядят как "foo", "документация" или "некоторые исправления", это не поможет, и вы действительно хотите SHA id ad1c77 или содержимое патча.

Здесь, как узнать реальное тождество F:

Когда он перечисляет конфликт переустановки, он скажет что-то вроде:

Patch failed at 0001 commit message for F

Теперь просмотрите .git/rebase-apply/, где вы найдете файл исправления 0001:

$ ls .git/rebase-apply
0001          head-name     msg           orig-head     sign
0002          info          msg-clean     patch         threeway
apply-opt     keep          next          quiet         utf8
final-commit  last          onto          rebasing

Файл исправления содержит исходный код фиксации

$ head -1 .git/rebase-apply/0001
From ad1c7739c1152502229e3f2ab759ec5323988326 Mon Sep 17 00:00:00 2001

Затем вы можете посмотреть на это.

Должен быть более простой способ, но это работает.

Обратите внимание, что тот факт, что исправление не удалось, может быть связано с другой фиксацией (если вы переформатируете на общий предок HEAD и цель переадресации). Найти, что фиксация является более сложной, хотя вы можете попытаться выполнить перестановку в обратном порядке, чтобы найти ее:

$ git checkout D
$ git rebase G

Ответ 2

Во время git rebase, который останавливается, чтобы разрешить конфликты, следующая команда покажет конфликтную фиксацию (все это, а не только конфликтующие файлы), то есть ваша фиксация в настоящее время переигрывается/переустанавливается на новую базу, независимо где вы находитесь вверх:

git show $(< .git/rebase-apply/original-commit)

Если вы хотите видеть только конфликты для определенного конфликтующего файла (тот, который вы разрешаете), in-isol:

git show $(< .git/rebase-apply/original-commit) -- /path/to/conflicting/file

Никаких кошек не злоупотребляли при построении этого ответа:).

Ответ 3

cat .git/rebase-apply/original-commit

Учитывая это:

A---B---C---D
     \
      E---F---G

$ git checkout G
$ git rebase D

и учитывая, что существует конфликт слияния, пытающийся применить F:

A---B---C---D--E'--!
     \
      E---F---G

то в файле original-commit будет отображаться хэш F. Это "их" версия.

Кроме того, HEAD (.git/HEAD) будет E 'в этом случае. Это "моя" версия. HEAD ^ будет "базовой" версией.

Это верно для не менее git 1.7.9

Ответ 4

Не знаю, почему у меня нет .git/rebase-apply в моей ситуации. Для тех, кто в той же ситуации, вот моя вариация.

git show $(cat .git/rebase-merge/stopped-sha)

Или как псевдоним...

git config --global alias.sp='!git show $(cat .git/rebase-merge/stopped-sha)'