Вы можете определить с помощью git merge-base, если возможна быстрая перемотка вперед, но есть ли какой-то трюк git, чтобы определить, будут ли две ветки сливаться с какой-то стратегией без фактического выполнения слияния? Я знаю о git merge --no-commit --no-ff $BRANCH
, но это влияет на рабочий каталог, который я бы хотел избежать, поскольку это часть веб-службы.
Можно ли определить, будут ли две ветки git сливаться, не затрагивая рабочий каталог?
Ответ 1
Нет встроенного способа; для выполнения слияния требуется дерево работ. Увидеть, будет ли слияние работать (в общем случае), значит попробовать стратегию и посмотреть, что произойдет.
Однако вы можете проверить тривиальный случай: две ветки не касаются одних и тех же файлов. Найдите базу слияния, а затем проверьте, есть ли у git diff --name-only $merge_base branchA
и git diff --name-only $merge_base branchB
что-то общее.
В противном случае вам понадобится дерево работы, чтобы попробовать слияние. Вы можете легко создать второй - либо клонировать репозиторий, либо экономить место, просто создайте дерево работ. git-new-workdir
script (из git.git contrib directory) может помочь в этом; он создает новый репо, каталог .git
полон символических ссылок на исходный. Просто будьте осторожны, что в этом новом рабочем каталоге вы не изменяете ветвь, которую проверила оригинальная репо, - они выйдут из синхронизации, точно так же, как нажатие на текущую проверенную ветку события.
Ответ 2
Я сделал бы это, создав третью временную ветвь.
Предположим, вы хотите объединить ветвь branchFrom
в branchTo
. Затем он будет выглядеть следующим образом:
git checkout branchTo #only if not already at branchTo
git checkout -b branchTmp
git merge branchFrom
# see what happens
git checkout branchTo
git branch -d branchTmp
# act accordingly
Таким образом, вы получаете точные результаты, не вкручивая ни одну из ваших ветвей.
Ответ 3
TL;DR
Предположим, что вы выбрали "цель" вашего слияния, т.е. HEAD
, а ваш источник слияния - $BRANCH
:
git merge-tree `git merge-base $BRANCH HEAD` HEAD $BRANCH | grep "^<<<<<<<\|changed in both"
Подробнее
Предположим, что вы выбрали "цель" вашего слияния, т.е. HEAD
, а ваш источник слияния - $BRANCH
, сначала "найти как хороших общих предков, насколько возможно для слияния" :
git merge-base $BRANCH HEAD
Вышеизложенное должно выводить хеш-значение для фиксации; вызовите это значение $merge_base
.
Далее, показать трехстороннее слияние без касания индекса:
git merge-tree $merge_base HEAD $BRANCH
Вышеизложенное должно выводить "тривиальные результаты слияния и конфликтующие этапы на стандартный вывод".
Если HEAD
уже обновлен относительно $BRANCH
, выход не должен быть.
Если есть конфликты слиянием, вывод должен содержать маркеры конфликта Git. Вы можете определить, есть ли у него такая команда:
git merge-tree $merge_base HEAD $BRANCH | grep "^<<<<<<<"
Вы также можете искать текст, "измененный в обоих":
git merge-tree $merge_base HEAD $BRANCH | grep "changed in both"
Все приведенные выше команды в качестве однострочного (Bash):
git merge-tree `git merge-base $BRANCH HEAD` HEAD $BRANCH | grep "^<<<<<<<\|changed in both"
Это было адаптировано из этого ответа на этот вопрос:
Ответ 4
Вы не можете сделать это, не затрагивая рабочий каталог, но можете сделать это, не затрагивая ваши текущие изменения.
git stash
git merge ...
Woops
git reset --hard HEAD
git stash apply
Вы получите то, что вам нужно.