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

Можно ли определить, будут ли две ветки git сливаться, не затрагивая рабочий каталог?

Вы можете определить с помощью git merge-base, если возможна быстрая перемотка вперед, но есть ли какой-то трюк git, чтобы определить, будут ли две ветки сливаться с какой-то стратегией без фактического выполнения слияния? Я знаю о git merge --no-commit --no-ff $BRANCH, но это влияет на рабочий каталог, который я бы хотел избежать, поскольку это часть веб-службы.

4b9b3361

Ответ 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

Вы получите то, что вам нужно.