Является ли `git merge` способным отображать каждое изменение (w.r. для общего предка) в качестве конфликта слияния?

Предположим, что у нас есть файл common_ancestor (master)

ok
ok
ok
ok
ok

Оттуда мы изменим и зафиксируем master на

ok
change not ok (looking back)
ok
ok
ok
latest change
ok

Теперь у нас есть лучшая идея, проверка common_ancestor и изменение его на

ok
ok
ok
This is a really good change
ok
ok

и зафиксировать в новой ветке dev. Поскольку мне нужны некоторые разработки из master, я хочу объединить dev в master, но я хочу решить для каждого изменения сохранить или нет. Я попробовал

git checkout master
git merge dev --no-ff --no-commit

Но я не понял, что я expected. Я ищу что-то вроде:

ok
<<<<HEAD
change not ok (looking back)
====
>>>> HASH
ok
ok
<<<<HEAD
====
This is a really good change
>>>> HASH
ok
<<<<HEAD
latest change
====
>>>> HASH

где видны маркеры конфликтов (см. здесь).

Изменить. Что я видел, git merge dev --no-ff --no-commit не выделяет изменения - @VonC объяснил, почему маркеры конфликтов не видны (потому что конфликтов нет!).

Ответ 1

В вашем случае объединение dev в master будет просто:

  • добавьте изменение от dev "This is a really good change"
  • сохранить внесенное изменение в master "change not ok (looking back)"

Это потому, что эти изменения не были сделаны в одном и том же месте в файле: в той же строке нет одновременной модификации.
Это означает, что конфликта нет.

Если вы хотите посмотреть слияние (но до фиксации слияния), вы можете настроить пользовательский драйвер слияния.

[merge "verify"]
        name = merge and verify driver
        driver = ./merge-and-verify-driver %A %O %B

Вы можете связать этот драйвер с вашими файлами в файле . gitattributes.

*.R merge=merge and verify driver

С merge-and-verify-driver.sh a script, который всегда возвращает 1, чтобы указать, что конфликт был, даже если слияние было фактически разрешено без конфликтов (что здесь имеет место: конфликта в вашем слиянии).

#!/bin/bash
git merge-file "${1}" "${2}" "${3}"
exit 1

Примечание. В случае конфликтов у вас будет больше информации с помощью:

git config --global merge.conflictstyle diff3

Ответ 2

Как отмечал @VonC, неправильно рассматривать различия в двух версиях как конфликты. Поэтому он ответил на мой вопрос. Чтобы достичь своей цели, я использовал

git difftool -t=kdiff3 dev master

и инструмент слияния. В kdiff3 каждая разница подсвечивается, и вы можете выбрать, какую версию для каждой строки вы хотите сохранить. См. Также здесь для видеоурока.

Ответ 3

Я хочу объединить dev в master, но я хочу решить для каждого изменения, сохранить или нет.

Это вызывает интерактивную перезагрузку:

git branch dev_rebase dev
git checkout dev_rebase
git rebase -i master

Тогда идите оттуда. git help rebase, поиск "интерактивного режима" должен дать вам идеи. Просто удалите строки (коммиты), которые вы хотите пропустить, и используйте edit, если хотите взять части коммита, но вам нужно отредактировать файлы.

Если что-то идет ужасно неправильно, dev будет в любом случае не затронут.

# if happy:

git checkout master
git merge --no-ff dev_rebase

# for good measure:

git checkout dev
git rebase master