Можно ли определить, будут ли две git-ветки сливаться чисто, не затрагивая рабочий каталог? - PullRequest
25 голосов
/ 15 мая 2010

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

Ответы [ 4 ]

29 голосов
/ 09 февраля 2012

Я бы сделал это, создав третью временную ветвь. Допустим, вы хотите объединить ветку 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

Таким образом, вы получите точные результаты, не привинчивая ни одной из ваших ветвей.

9 голосов
/ 15 мая 2010

Там нет встроенного пути; рабочее дерево требуется для выполнения слияния. Понять, сработает ли слияние (в общем случае), означает попробовать стратегию и посмотреть, что произойдет.

Однако вы можете проверить тривиальный случай: две ветви не касаются одних и тех же файлов. Найдите базу слияния, а затем проверьте, имеют ли git diff --name-only $merge_base branchA и git diff --name-only $merge_base branchB что-нибудь общее.

В противном случае вам понадобится рабочее дерево, чтобы попробовать объединение. Вы можете легко создать второе - либо клонировать репозиторий, либо сэкономить место, просто создайте рабочее дерево. Сценарий git-new-workdir (из каталога contrib git.git) может помочь с этим; он создает новый репозиторий, каталог .git которого заполнен символическими ссылками на исходный. Только будьте осторожны, что в этом новом рабочем каталоге вы не модифицируете ветку, которую исходное хранилище извлекло - они выйдут из синхронизации, точно так же, как нажатие на текущую извлеченную ветку испортило все.

7 голосов
/ 02 июня 2012

TLDR

Предполагается, что ваша цель слияния извлечена, т. Е. 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"

Это был адаптирован с этот ответ на этот вопрос:

1 голос
/ 28 мая 2010

Вы не можете сделать это без влияния на рабочий каталог, но вы можете сделать это без влияния на текущие изменения.

git stash
git merge ... 

Woops

git reset --hard HEAD
git stash apply

Получит вам то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...