Как проверить слияние без фактического слияния

Есть ли способ имитации git merge между двумя ветками, текущей рабочей веткой и мастером, но без внесения каких-либо изменений?

У меня часто возникают конфликты, когда я должен сделать git merge, Есть ли способ имитации слияния в первую очередь?

9 ответов

Решение

Я не думаю, что есть способ имитировать то, что произойдет, пока вы не попробуете слияние. Однако, если вы убедитесь, что на выходе git status пусто до того, как вы сделаете слияние, вполне безопасно просто пойти и попробовать. Если у вас возникли конфликты, вы можете немедленно вернуться в состояние, в котором вы были раньше:

git reset --merge

Начиная с git 1.7.4, вы также можете прервать слияние, выполнив:

git merge --abort

(Как объясняется в сообщении о фиксации, добавляющем эту опцию, это было добавлено для соответствия git rebase --abort и так далее.)

Ты можешь использовать git merge --no-commit чтобы предотвратить слияние на самом деле, и если вам не нравится, как слияние происходит, просто верните исходную головку.

Если вы определенно не хотите завершать слияние, даже если это ускоренная перемотка (и, следовательно, по определению не имеет конфликтов), вы можете добавить --no-ff также.

Если я хочу сравнить изменения в ветке темы с master, я считаю, что проще и безопаснее сделать следующее:

git checkout master
git checkout -b trial_merge
git merge topic_branch

После завершения слияния легко увидеть консолидированное изменение из основного

git diff master

Когда закончите, просто удалите ветвь trial_merge

git checkout master
git branch -D trial_merge

Таким образом, основная ветвь никогда не меняется.

Вот решение, которое я нашел: git merge-treeвыполняет слияние "в памяти" и печатает разницу, не касаясь вашего рабочего каталога. Вы даже можете протестировать ветку, не проверяя ее.

Получите разницу слияния

Сначала сделайте это, чтобы убедиться, что ваш репозиторий знает обо всех удаленных ветках:

$ git fetch --all

Теперь используйте этот фрагмент bash, чтобы увидеть, как ветвь $branch будет сливаться в $master:

$ branch='feature'
$ git merge-tree $(git merge-base $branch master) master $branch

В ваш рабочий каталог или индекс не вносятся изменения. Это пробное слияние.

Выберите информацию из вывода

На выходе получается разница. Если ветка была объединена, она будет пустой.

Чтобы узнать, есть ли конфликты, используйте grep для <<<:

$ git merge-tree $(git merge-base $branch master) master $branch | fgrep '<<<'

Чтобы извлечь различия конфликтов, используйте sedизвлекать строки между <<< и >>>:

$ git merge-tree $(git merge-base $branch master) master $branch | \
  sed -ne '/^\+<<</,/^\+>>>/ p'

Особенности

  • Разница будет пуста, если ветка уже объединена
  • Используйте grep/sed для извлечения информации о конфликтах
  • Использовать origin/feature для тестирования веток, с которыми вы никогда не работали
  • Может использоваться, чтобы увидеть, как две ветви разошлись

Добавить в избранное

Получите разницу слияния:

git config --global alias.mergediff '!f(){branch= "$ 1"; в ="$2"; git merge-tree $(git merge-base "$branch" "$into") "$into" "$branch"; };f '

Применение:

$ git mergediff <feature-branch> <merge-into>
$ git mergediff feature master

Получите конфликты слияния:

git config --global alias.mergetest '!f(){git mergediff $@ | sed -ne "/ ^ +<<< /,/^+>>>/ p"; };f '

Применение:

$ git mergetest <feature-branch> <merge-into>
$ git mergetest feature master

Почему бы просто не создать одноразовую ветку (git checkout -b) и выполнить там тестовое слияние?

Я использую:

git merge --ff-only

согласно документации:

Отказаться от слияния и выхода с ненулевым статусом, если текущий HEAD уже не обновлен или слияние не может быть разрешено как ускоренная перемотка вперед.

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

Я был в состоянии использовать git merge --abort, относительно недавно. Однако это можно использовать только в случае конфликта слияния. Если вы уверены, что не захотите совершать коммит, используйте другие упомянутые выше методы.

Я хотел бы добавить к превосходному ответу @kolypto - (это должен быть комментарий, но у меня нет баллов).

На странице руководства в разделе «Ошибки, которых следует избегать» указано:

НЕ просматривайте полученное дерево верхнего уровня, чтобы попытаться определить, какие файлы конфликтуют [...] существует множество типов конфликтов, которые не могут быть представлены маркерами конфликта (изменение/удаление, конфликт режимов, двоичный файл изменен с обеих сторон, конфликты файлов/каталогов). , различные варианты конфликтов переименований и т. д.)

...так что делаюна выходе — это неправильный способ определить наличие конфликтов. Вместо этого вам следует проверить код выхода:

Для успешного слияния без конфликтов статус выхода равен 0. Если слияние имеет конфликты, статус выхода равен 1. Если слияние не может быть завершено (или запущено) из-за какой-либо ошибки, статус выхода равен 1. что-то отличное от 0 или 1 (и результат не указан).

Пример:

      #!/bin/bash

branch='myFeatureBranch'
ret=0
mergeTest=`git merge-tree --write-tree master $branch` || ret=$?
if [ ! $ret -eq 0 ];then
   echo "Merge would result in conflicts:"
   echo "$mergeTest" | grep CONFLICT
   ## Do something useful here
   exit 1
fi

Я не знаю точно, относится ли это к вашему делу, но ваш вопрос помните, что иногда я запускаю функцию, я фиксирую ее в течение нескольких дней и объединяю разработку с ней много раз.

На этом этапе я теряю контроль над точными файлами, которые я изменил, и я буду знать это только тогда, когда моя функция будет закрыта и мой код будет разрабатываться.

В этом случае, хороший способ узнать, какие изменения вы сделали (а не какие-либо из слияний), использует Sourcetree.

Вы должны щелкнуть правой кнопкой на базовой ветви и выбрать Diff Against Current:

Возможность Sourcetree узнать разницу между двумя ветками

Затем sourcetree покажет вам все модификации, которые будут объединены, если вы объедините свою ветку с базовой веткой.

Результаты

Конечно, это не покажет вам конфликты, но это полезный инструмент в слияниях.

Другие вопросы по тегам