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


294

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

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

Я получил сообщение об ошибке, error: The branch 'experiment' is not fully merged.я немного новичок в Git, и я не знаю, насколько больше я мог бы объединить две ветви. Что мне здесь не хватает?


2
Помогает ли вам этот пост? stackoverflow.com/questions/1710894/…
Chrisdigital

2
Это иногда возникает, когда я сделалgit commit --amend
Arcolye

12
Также - Помните, что это сообщение появится после squash: stackoverflow.com/q/41946475/109941
Джим Г.

Я думаю, что наиболее распространенный сценарий, вам просто нужно вытащить вновь слитые изменения, прежде чем удалить ветку локально.
RaisinBranCrunch

Ответы:


313

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

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

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

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

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

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

--cherry-pick

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


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

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


24
Спасибо. Ключевая фраза была «содержит коммиты, которые недоступны из других ссылок». Хотя я больше не нуждался в ветви эксперимента и уже слил ее с master, и планировал удалить ее из источника, git не будет счастлив, пока я не перенесу изменения в эксперимент в origin. Я думаю, что это предупреждение было своего рода проверкой работоспособности.
Мелоджа в

35
-1 «Это означает, что ветвь, которую вы собираетесь удалить, содержит коммиты, недоступные из других ссылок.» Это не правильно. Предупреждение означает, что ветвь недоступна ни из ее восходящего потока (если он есть), ни из текущего заголовка. Смотрите man-страницу git-branch.
Слёске

3
@TachyonVortex Хорошая ссылка. Команда git branch -vv действительно прояснила, что происходит для меня.
Джейсон Мэсси

11
@sleske Спасибо за комментарий - этот ответ действительно должен быть отредактирован. Обидно, что за это высоко проголосовали, потому что основное объяснительное предложение неверно. У меня просто была эта проблема, и я потратил много времени, пытаясь выяснить, в чем проблема, и просто ветка удаленного отслеживания была удалена как часть запроса на извлечение, и в то время, когда я извлек изменения из master на местном филиале. Единственной «проблемой» не было нахождение удаленной ветви отслеживания, которая была удалена (и я пытался удалить локальную ветку по той же причине).
Ely

3
Да, это может произойти просто при попытке удалить локальную ветку, если вы находитесь на ветке, отличной от той, на которой вы ее создавали. «Коммиты, которые не достижимы от любого другого реф», неверны и излишне страшны!
Амальговинус

80

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


2
Часть о текущей HEAD исправила это для меня. Мой мастер отличался от ветки, из которой я создал конфликтующую ветку: D
viki.omega9

1
Для кого-то, изучающего git, слово «текущий» кажется излишним с «HEAD»? Там нет такого понятия , как uncurrent ГОЛОВЫ - ГОЛОВА по определению является текущей ветвью. Я что-то упускаю? Я полагаю, вы могли бы сказать «текущая ветка» или «ГОЛОВА», но не «текущая ГОЛОВА».
Марк Лаката

Есть ли способ изменить / настроить это (например, всегда ли это проверять origin/master?) Я полагаю, что origin/masterсначала проверить не слишком обременительно, но это похоже на странный поток - почему мне нужно проверить origin/masterлокально только для того, чтобы вы убедились, что мои изменения там объединены?
Alec

15

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

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

git log feature-branch ^master --no-merges

14

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


7
Не похоже, что это конкретная проблема здесь, но я столкнулся с проблемой, которую вы описываете только сейчас, так что спасибо!
Даниэль Бакмастер,

4

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 подтвердить полностью объединенный статус для вас.


1
Ключ «полностью слит в текущую ветку». У меня была ветка X 'из X, полностью слитая обратно в X, и я уже удалил origin / X'. Но с проверкой Y я получил это предупреждение. Когда я выписался, XI смог удалить X '. Это довольно глупо, я думаю.
Лоуренс Дол

2
Этот ответ плагиат отсюда без указания авторства chimera.labs.oreilly.com/books/1230000000561/…
Марк Лаката

3

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

git checkout experiment
git merge --no-commit master

git diff --cached

Примечание: это показывает изменения в masterкоторых нет experiment.

Не забудьте:

git merge --abort

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


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

3

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

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

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».

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


3

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

Git Log - Cherry Master ... экспериментальный

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

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

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

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


1

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


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.