Принудительное «git merge» объявляет все различия как конфликт слияния

В 'git merge' Я хотел бы, чтобы любое различие, даже если обычно это не конфликт слияния, считалось конфликтом слияния. Затем с помощью «git mergetool»; Я могу видеть и разрешать каждую разницу. Я попытался указать "* -merge" в .gitattributes, но это, похоже, не сработало:

$ git checkout master
Switched to branch 'master'
$ ls
foo.c
$ git merge add-on
Updating a628824..2219552
Fast-forward
  0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar.c
$ cat .gitattributes 
* -merge
$ ls
bar.c   foo.c

Для вышеупомянутого «дополнения git merge» Я ожидал конфликта слияния для «bar.c»; без базовой версии, без локальной версии и удаленной версии. [править] Как предлагается в одном ответе, слияние не произошло выше. Вот случай, когда я принудительно произвел слияние, по-прежнему нет желаемого конфликта слияния

$ git merge --no-ff add-on
Merge made by the 'recursive' strategy.
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bing.c

Обратите внимание, что в приведенном выше «bing.c» на самом деле пусто; но это не является проблемой, поскольку предоставление непустого файла все еще объединяется. [править 2] Я попытался --no-commit с таким результатом:

$ git merge --no-ff --no-commit add-on
Automatic merge went well; stopped before committing as requested
$ git status
# On branch master
# Changes to be committed:
#
#   new file:   boom.c
#
$ git mergetool
No files need merging
$ cat .gitattributes 
* -merge

Что мне не хватает? Есть ли способ подтвердить, что «.gitattributes»? привыкаешь / читаешь?

Ответы на вопрос(3)

У меня есть подобное желание, и я не смог сделать это с помощью автоматических инструментов. Вот полуавтоматическое решение:

Отmaster, объединитьadd-on и вручную разрешить изменения:

Начните с:

git merge --no-ff --no-commit add-on

Затем для каждого измененного файла выполните:

git show master:path/to/file > from_master
git show add-on/to/file > from_add-on
kdiff3 --qall from_master from_add-on -o path/to/file
git add path/to/file

В заключение,

git commit
Why this 90% solution?

Это решение объединяется даже в «очевидных ситуациях» и это не вынуждает меня устанавливать .gitattributes, чтобы я мог выполнить «ручное слияние»; поведение зависит от того, с кем я объединяюсь и почему, а не от того, с какими файлами я объединяюсь.

Решение Вопроса

Вы не слились. Ваша командаgit merge add-on выполнил «ускоренную перемотку вперед», что означает, что он только что переместил головку ветви. Это потому что вашadd-on ветка сошла с кончика твоегоmaster ветвь уже, так что слияние не требуется. Если вы бежитеgit log вы увидите, что коммитов слияния нет.

В принципе, до слияния это выглядело так:

              master
             /
o---o---o---o           add-on
             \         /
              o---o---o

и слияние только что переместилоmaster указатель на конец строки:

                          master, add-on
                         /
o---o---o---o---o---o---o

Если вы хотите форсировать слияние, передайте--no-ff флаг, как вgit merge --no-ff add-on.

После дальнейшего размышленияmerge атрибут не будет делать то, что вы хотите. Это относится только к слияниям на уровне файлов, что означает, что обе стороны слияния имеют изменения в конкретном файле. Если изменения внесены только одной стороной (как в вашем случае), слияние на уровне файлов не выполняется и измененный файл принимается безоговорочно.

Ваш лучший выбор, вероятно, использоватьgit merge --no-ff --no-commit add-on произвести слияние, но фактически не совершать. Теперь вы можете проверить результаты и настроить их по своему вкусу, прежде чем совершать слияние. Если вы хотите принимать изменения для каждого отдельного блока, вы можете сделать что-то вродеgit reset сбросить индекс, а затемgit add -p сделать постановку за кусок.

 GoZoner13 апр. 2012 г., 00:47
Да, посмотрите сейчас и подтвердите.
 GoZoner12 апр. 2012 г., 23:07
Благодарю. Я попытался еще раз с помощью "git merge --no-ff add-on" - все еще нет желаемого конфликта слияния.
 12 апр. 2012 г., 23:50
@ GoZoner: Нет конфликта слияния, потому что не было слияний на уровне файлов. Только одна сторона слияния имела какие-либо изменения в файле, поэтому эта сторона была выбрана безоговорочно.merge Атрибут применяется только в случае слияния на уровне файлов (например, изменения произошли с обеих сторон, и необходимо вызвать драйвер слияния).
 GoZoner13 апр. 2012 г., 00:14
Правильно, но на основании документации по атрибутам git для 'unset merge', я ожидаю, что конфликт слияния будет вынужден возникнуть. Возможно, "* -merge" не является правильным способом получить желаемое поведение (каждое различие, даже если оно обычно может быть объединено, приводит к конфликту, который я затем могу явно разрешить с помощью трехстороннего объединения - так что я могу убедиться, что слияние семантически правильно, не просто текстуально правильно).
 13 апр. 2012 г., 00:16
@GoZoner: с man-страницы: & quot; Слияние атрибутов влияет на то, как объединяются три версии файла, когдаfile-level merge необходимо во время git merge & quot; (акцент мой). У вас нет слияния на уровне файлов. Я уже обновил свой ответ альтернативным предложением.

Вы можете попробовать:

git merge --no-commit

Что заставит GIT не фиксировать изменения слияния. В качестве альтернативы, если вы хотите, чтобы он фиксировался, когда нет конфликта, но не терял ветку с исходным кодом, это no-ff:

git merge --no-ff

Оба могут быть использованы при необходимости.

Больше информации здесь:Почему git ускоряет слияние по умолчанию?

 GoZoner12 апр. 2012 г., 23:07
Благодарю. Я попытался еще раз с помощью "git merge --no-ff add-on" - все еще нет желаемого конфликта слияния.
 12 апр. 2012 г., 23:10
А ты пробовал--no-commit? Тот факт, что он не фиксирует, дает вам возможность выбрать, что принимать, а что не принимать. Вы все еще не получитеconflict обязательно, потому что нет.
 GoZoner12 апр. 2012 г., 23:16
Я постараюсь заметить, что в справке по атрибутам gitatributes указано «Unset: принять версию текущей ветки за предварительный результат слияния и объявить, что слияние имеет конфликты». Это подходит для двоичных файлов, которые не имеют четко определенной семантики слияния. & Quot; Объявление конфликтов должно остановить слияние до любого коммита.

Ваш ответ на вопрос