Ошибка Git: ветка 'x' не полностью объединена

Вот команды, которые я использовал из основной ветки

git branch experiment
git checkout experiment

Затем я внес некоторые изменения в свои файлы, зафиксировал изменения и отправил новую ветку на GitHub.

git commit . -m 'changed files'
git push -u origin experiment

Позже я решил объединить свою экспериментальную ветвь с основной веткой.

git checkout master
git merge experiment

Наконец, я внес изменения в GitHub.

git push -u origin master

Все шло хорошо, пока я не попытался удалить ветку эксперимента, используя

git branch -d experiment

Я получил сообщение об ошибке:

ошибка: ветка "эксперимент" объединена не полностью.
Если вы уверены, что хотите удалить ее, запустите "git branch -D эксперимент".

Я немного новичок в git, и я не знаю, сколько еще я мог бы объединить две ветки. Что мне здесь не хватает?


person mellowsoon    schedule 25.09.2011    source источник
comment
Этот пост тебе помогает? stackoverflow.com/questions/1710894/   -  person Chrisdigital    schedule 26.09.2011
comment
Это иногда возникает, когда я git commit --amend   -  person Arcolye    schedule 12.07.2014
comment
Также - помните, что это сообщение появится после squash: stackoverflow.com/q/41946475/109941   -  person Jim G.    schedule 29.01.2018
comment
Я думаю, что наиболее распространенный сценарий заключается в том, что вам просто нужно вытащить свои недавно объединенные изменения, прежде чем удалять ветку локально.   -  person RaisinBranCrunch    schedule 17.04.2019


Ответы (12)


Примечание. Формулировка изменена в ответ на комментарий. Спасибо @slekse
Это не ошибка, это предупреждение. Это означает, что ветка, которую вы собираетесь удалить, содержит коммиты, которые недоступны ни из: ее восходящей ветки или HEAD (текущая проверенная ревизия). Другими словами, когда вы можете потерять коммиты¹.

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

Поэтому вы можете избежать предупреждения, проверив ветку, которая содержит коммиты, о которых вы не ссылаетесь, удалив эту другую ветку. ²

Вам нужно будет убедиться, что вы действительно не упускаете ни одного важного коммита:

git log --graph --left-right --cherry-pick --oneline master...experiment

Это даст вам список всех, не используемых в ветвях. Если вам интересно, разница может быть и без --cherry-pick, и эта разница вполне может быть причиной предупреждения, которое вы получаете:

--cherry-pick

Пропустите любую фиксацию, которая вводит те же изменения, что и другая фиксация на другой стороне, когда набор коммитов ограничен симметричной разницей. Например, если у вас есть две ветки, A и B, обычный способ перечислить все коммиты только на одной из них - с помощью --left-right, как в примере выше в описании этой опции. Тем не менее, он показывает коммиты, выбранные из другой ветки (например, 3-я на b может быть выбрана из ветки A). С этой опцией такие пары коммитов исключаются из вывода.


¹ по умолчанию они действительно собираются мусором только через некоторое время. Кроме того, команда git-branch не проверяет дерево ревизий всех ветвей. Предупреждение сделано, чтобы избежать очевидных ошибок.

² (Я предпочитаю вместо этого просто принудительно удалить удаление, но вы, возможно, захотите получить дополнительную уверенность).

person sehe    schedule 25.09.2011
comment
Спасибо. Ключевая фраза была содержит коммиты, недоступные из любой другой ссылки. Несмотря на то, что мне больше не нужна ветвь эксперимента, я уже слил ее с мастером и планировал удалить ее из источника, git не обрадуется, пока я не перенесу изменения в эксперимент в источник. Думаю, это предупреждение было своего рода проверкой на вменяемость. - person mellowsoon; 26.09.2011
comment
-1 Это означает, что ветка, которую вы собираетесь удалить, содержит коммиты, недоступные из любой другой ссылки. Это не так. Предупреждение означает, что ветвь недоступна ни из своего восходящего потока (если он есть), ни из текущего HEAD. См. Справочную страницу git-branch. - person sleske; 07.09.2012
comment
@sleske +1 Мне разрешили удалить ветку после того, как я нажал репо. - person DBedrenko; 11.07.2014
comment
@TachyonVortex Хорошая ссылка. Команда git branch -vv действительно прояснила для меня, что происходит. - person Jason Massey; 20.11.2014
comment
@sleske Спасибо за комментарий - этот ответ действительно стоит отредактировать. Жаль, что за него проголосовали очень много, потому что основное пояснительное предложение неверно. У меня просто была эта проблема, и я потратил досадно долгое время, пытаясь выяснить, в чем проблема, и просто ветка удаленного отслеживания была удалена как часть запроса на вытягивание, и за время, прошедшее с тех пор, как я получил изменения от мастера в местном филиале. Единственная «проблема» заключалась в том, что не удалось найти удаленную ветку отслеживания, которая была удалена (и я пытался удалить локальную ветку по той же причине). - person ely; 22.12.2014
comment
Да, это может произойти просто при попытке удалить локальную ветку, если вы находитесь в другой ветке, чем та, в которой вы были при ее создании. Коммиты, недоступные для других ссылок, неверны и напрасно пугают! - person Amalgovinus; 31.07.2015
comment
В чем разница между .. и ...? Последнее появляется в ответе, но первое показалось мне более полезным в моем случае. - person Dror; 11.09.2015
comment
@Dror, и вы найдете man git-rev-parse даже полезнее! Короче говоря, ... сравнивает оба способа, i.o.w. он не предполагает, что только правая сторона может содержать уникальные коммиты. - person sehe; 12.09.2015
comment
@sleske и другие: Наконец-то пришло время снова протестировать это и ужесточить формулировку. Спасибо за ваши комментарии. - person sehe; 09.10.2015
comment
Ключ в том, что боковая ветвь должна быть полностью объединена с текущей ветвью. У меня была ветка X 'от X, полностью слитая обратно в X, и я уже удалил origin / X'. Но после проверки Y я получил это предупреждение. Когда я проверил X, я смог удалить X '. Думаю, это довольно глупо. - person Lawrence Dol; 16.03.2016
comment
-1: Почему предупреждение? Прежде всего, он гласит: error: Ветвь «пробная» не объединена полностью. Во-вторых, предупреждения не препятствуют операции, о которой они предупреждают. В этом их окончательное отличие от ошибок. Этот делает. Это похоже на ошибку, действует как ошибка, так почему вы называете это предупреждением? - person Sz.; 25.02.2018
comment
@Sz. Это предупреждение о безопасности. Вы можете отменить это. Так что безопасность - это то, что приводит к ошибке, это всего лишь парадокс, а не противоречие. Хорошо, что git решил обработать предупреждение о безопасности как ошибку. Но логически это предупреждение пользователя о регулярной ситуации, которая обычно возникает. Когда я сказал, что это не ошибка, я отвечал на OP в том смысле, что это не то, что вы делаете неправильно. - person sehe; 25.02.2018
comment
Это даст вам список всех неразделенных между ветвями. Поскольку это двухстороннее сравнение, как мне узнать, из какой ветки отсутствуют перечисленные коммиты? - person kerner1000; 31.10.2018
comment
@ kerner1000 вы еще не пробовали? Параметр --left-right отмечает каждую фиксацию знаком < или >. Недавний git также поддерживает --cherry-mark, чтобы также отображать общие коммиты - person sehe; 31.10.2018
comment
@sehe, да, пробую. Хотя кажется, что он перевернут ... --left-right [] develop...issue показывает мне коммиты, отмеченные <, но они точно находятся в разработке. - person kerner1000; 31.10.2018
comment
Этот git не проверяет каждую ветку, ИМХО - это ошибка. Либо предупреждать, когда это верное и точное предупреждение, либо никогда не предупреждать. Предупреждение, когда иногда это правда, а иногда нет, бесполезно. - person studog; 12.12.2018

Как отметил Дрю Тейлор, при удалении ветки с помощью -d учитывается только текущий HEAD при определении того, "полностью ли объединена" ветвь. Он будет жаловаться, даже если ветка объединена с какой-либо другой веткой. В этом отношении сообщение об ошибке может быть более ясным ... Вы можете либо проверить объединенную ветку перед удалением, либо просто использовать git branch -D. Заглавная -D полностью отменяет проверку.

person drwowe    schedule 02.04.2012
comment
Часть о текущем HEAD исправила это для меня. Мой мастер отличался от ветки функций, из которой я создал конфликтующую ветку: D - person viki.omega9; 24.01.2015
comment
Для тех, кто изучает git, слово «текущий» кажется излишним с HEAD? Нет такой вещи, как нетекущий HEAD - HEAD по определению является текущей ветвью. Я что-то упускаю? Я полагаю, вы могли бы сказать текущую ветку или HEAD, но не текущую HEAD. - person Mark Lakata; 11.01.2017
comment
Есть ли способ изменить / настроить это (например, всегда проверять на origin/master?) Я думаю, проверка origin/master сначала не слишком обременительна, но это просто похоже на какой-то странный поток - зачем мне проверять out origin/master локально только для того, чтобы вы могли убедиться, что мои изменения там объединены? - person Alec; 09.08.2017
comment
@Alec вы всегда можете создать псевдоним. В master нет ничего особенного. git не делает никаких предположений (или требований) об именах или важности ветвей, пользователь должен четко указать, что мы хотим объединить / сравнить / проверить и т. д. git даже не предполагает, что удаленный master более важен, чем ваши локальные ветки ! И для ясности, origin/master - это ваша локальная копия удаленного master по адресу origin, которая может совпадать, а может и не совпадать с вашим локальным master (в зависимости от того, выполняли ли вы выборку или извлечение). Вы оформляете заказ master. Редко бывает хорошая причина оформить заказ origin/master. - person Zim; 09.07.2020
comment
@Zim В любом совместном проекте я избегаю наличия локальной главной ветки, я всегда использую origin / master (если вам интересно: alecb.me/dont-checkout-master) - person Alec; 09.07.2020

Я попробовал ответить, но это не сработало.

Чтобы найти коммиты, которые не были объединены, просто используйте:

git log feature-branch ^master --no-merges
person qwertzguy    schedule 17.09.2013
comment
Результат этого метода был гораздо более понятным, чем предложение в принятом ответе. - person pauljohn32; 11.06.2021

Это случилось со мной сегодня, когда я объединял свою самую первую функциональную ветку обратно в master. Как некоторые говорили в потоке в другом месте на SO, уловка заключалась в переключении обратно на мастер перед попыткой удалить ветку. Вернувшись в мастер, git был счастлив удалить ветку без каких-либо предупреждений.

person Drew Taylor    schedule 22.02.2012
comment
Не похоже, что это конкретная проблема, но я столкнулся с проблемой, которую вы только что описали, поэтому спасибо! - person Daniel Buckmaster; 03.10.2012

Самое простое решение с объяснением (дважды проверено решение) (сталкивался с проблемой раньше)

Проблема в следующем:

1- Я не могу удалить ветку

2- Терминал продолжает отображать предупреждающее сообщение о том, что есть некоторые коммиты, которые еще не утверждены.

3- зная, что я проверил мастер и ветку, и они идентичны (обновлены)

решение:

git checkout master
git merge branch_name
git checkout branch_name
git push
git checkout master
git branch -d branch_name

Объяснение:

когда ваша ветка подключена к вышестоящей удаленной ветке (на Github, bitbucket или что-то еще), вам нужно объединить (протолкнуть) ее в мастер, и вам нужно протолкнуть новые изменения (коммиты) в удаленное репо (Github, bitbucket или что угодно) из ветки,

то, что я сделал в своем коде, - это то, что я переключился на master, затем слил ветку с ней (чтобы убедиться, что они идентичны на вашем локальном компьютере), затем я снова переключился на ветку и отправил обновления или изменения в удаленный онлайн репо с помощью "git push".

после этого я снова переключился на мастер и попытался удалить ветку, и проблема (предупреждающее сообщение) исчезла, и ветка была успешно удалена

person Elta3lab    schedule 14.01.2018

Git предупреждает, что вы можете потерять историю, удалив эту ветку. Даже если на самом деле он не удалит какие-либо коммиты сразу, некоторые или все коммиты в ветке станут недоступными, если они также не являются частью какой-либо другой ветки.

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

Однако Git не проверяет все остальные ветки в репозитории; только два:

  1. Текущая ветка (HEAD)
  2. Восходящая ветка, если есть

«Восходящая ветвь» для experiment, как и в вашем случае, вероятно, origin/experiment. Если experiment полностью объединен с текущей веткой, Git удаляет его без жалоб. Если это не так, но он полностью объединен в своей восходящей ветке, Git продолжает выводить предупреждение, которое выглядит примерно так:

warning: deleting branch 'experiment' that has been merged
to 'refs/remotes/origin/experiment', but not yet merged to
HEAD.
Deleted branch experiment (was xxxxxxxx).

Где xxxxxxxx указывает идентификатор фиксации. Полное слияние в своем восходящем потоке означает, что коммиты в experiment были отправлены в исходный репозиторий, так что даже если вы потеряете их здесь, они, по крайней мере, могут быть сохранены в другом месте.

Поскольку Git не проверяет другие ветки, можно безопасно удалить ветку, потому что вы знаете, что она полностью слита с другой; вы можете сделать это с помощью параметра -D, как указано, или сначала переключиться на эту ветку и позволить Git подтвердить за вас полностью объединенный статус.

person troore    schedule 11.12.2014
comment
Ключ полностью объединен в текущую ветку. У меня была ветка X 'от X, полностью слитая обратно в X, и я уже удалил origin / X'. Но после проверки Y я получил это предупреждение. Когда я проверил X, я смог удалить X '. Думаю, это довольно глупо. - person Lawrence Dol; 16.03.2016
comment
Этот ответ является плагиатом отсюда без указания авторства chimera.labs.oreilly. ru / books / 1230000000561 / - person Mark Lakata; 11.01.2017

Вы можете просто выяснить:

git log --cherry master ... экспериментальный

--cherry опция является синонимом --right-only --cherry-mark --no-merges

На странице руководства git-log сказано

полезно ограничить вывод коммитами на нашей стороне и пометить те, которые были применены к другой стороне разветвленной истории, с помощью git log --cherry upstream ... mybranch, аналогично git cherry upstream mybranch.

К вашему сведению. --cherry-pick не включает эквивалентные коммиты, а --cherry-marks - нет. Полезно находить перебазирование и принудительно обновлять изменения между вышестоящей и совместной общедоступной ветвью.

person yongbin    schedule 26.03.2014

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

git checkout experiment
git merge --no-commit master

git diff --cached

Примечание. Здесь показаны изменения в master, которых нет в experiment.

Не забывайте:

git merge --abort

Когда вы закончите смотреть.

person ThorSummoner    schedule 20.05.2014
comment
@IgorGanapolsky Точно не знаю, хотя обычно man git-reset и команды сброса git достаточно для восстановления после проблем с состоянием. - person ThorSummoner; 19.09.2017

У меня не было ветки восходящего потока на моем локальном git. Я создал локальную ветку от мастера, git checkout -b mybranch. Я создал ветку с графическим интерфейсом bitbucket в восходящем git и переместил свою локальную ветвь (mybranch) в эту восходящую ветвь. Как только я сделал git fetch на моем локальном git, чтобы получить ветку восходящего потока, я мог сделать git branch -d mybranch.

person edW    schedule 31.10.2016

Я считаю, что флаг --force - это то, что вы действительно ищете. Просто используйте git branch -d --force <branch_name>, чтобы удалить ветку принудительно.

person Sergey Samoylenko    schedule 01.05.2020

Если вы выполнили слияние на Github и видите ошибку ниже. Вам необходимо получить (получить и зафиксировать) изменения с удаленного сервера, прежде чем он распознает слияние на вашем локальном сервере. После этого Git позволит вам удалить ветку, не выдавая ошибки.

ошибка: ветвь «x» не полностью объединена. Если вы уверены, что хотите его удалить, запустите 'git branch -D' x '.

person A Simple Programmer    schedule 16.10.2020

C:\inetpub\wwwroot\ember-roomviewer>git branch -d guided-furniture
warning: not deleting branch 'guided-furniture' that is not yet merged to
         'refs/remotes/origin/guided-furniture', even though it is merged to HEAD.
error: The branch 'guided-furniture' is not fully merged.
If you are sure you want to delete it, run 'git branch -D guided-furniture'.

Для меня решение было просто перенести функциональную ветку на удаленный. Потом, когда я побежал:

git push origin guided-furniture
/* You might need to fetch here */
git branch -d guided-furniture

Deleted branch guided-furniture (was 1813496).
person Epirocks    schedule 25.06.2020