Ветка Git разошлась после перебазирования

114

Я переустановил ветку локально, которая уже была отправлена.

Git сообщает, что моя ветка и пульт разошлись, и что:

"и имеют 109 и 73 различных коммитов соответственно"

Решит ли это нажатие моей ветки - т.е. следует ли этого ожидать после перезагрузки?

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

Ответы:

155

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

Поскольку вы уже отправили ветку, вам следовало бы выполнить слияние в исходной ветке, а не выполнять повторную привязку к ней. Можно «принудительно протолкнуть» вашу новую ветку (используя -fфлаг), но обычная отправка не сработает, потому что будет нарушена целостность истории веток. Если вы сотрудничаете с другими участниками этой ветки, принудительное продвижение - плохая идея, так как это может привести в замешательство других участников, если их история внезапно не совпадет.

TL; DR - Если вы не сотрудничаете, нажмите ветку с помощью push -f. Если да, сбросьте ветвь в предыдущее состояние и вместо этого слейте в исходную ветку.

Джейсон ЛеБрун
источник
1
«Поскольку вы уже отправили ветку, вам следовало выполнить слияние в исходной ветке» - почему?
Hammett
1
@HamiltonVerissimo Первое предложение Джейсона: «Когда вы переустанавливаете ветку, вы должны переписывать коммиты для любого коммита, который выше коммитов в ветке, на которую вы перебазируете». Несмотря на то, что изменения, зафиксированные в «вышеуказанных» коммитах, имеют одинаковое логическое содержание, они применяются к другой базе и, следовательно, являются разными коммитами с разными хешами. Если другие разработчики работают с предварительно перебазированной веткой, то выполнение git push -f будет чрезвычайно нарушать их рабочий процесс. Таким образом, поскольку эта ветка была перенесена в общедоступный источник, он должен был объединиться.
awolf
4
вы также можете использовать push --force-with-lease, если не уверены, что кто-то уже что-то нажимал.
Консоль
1
@ jason-lebrun. Разве не недостатком слияния исходящих изменений не является то, что вы можете перезаписать свою работу без предупреждения? Обнаруживаются ли конфликты слияния так же, как и при ребазировании? Например, если я удалю раздел из файла в своей ветке, потому что он больше не нужен, но кто-то другой внес тривиальные изменения в тот же раздел в восходящем потоке, например, удаление некоторого пробела или какое-то глобальное действие поиска / замены, не будет слияние этого поверх моей ветки заменить мое удаление их тривиально измененной версией?
Крис Блум,
1
Слияние другой ветки с вашей - неплохая идея? Например, слияние мастера с функциональной веткой - не создаст ли это для этого новую фиксацию? Не приведет ли это к дополнительной фиксации после этой функциональной ветки, если позже будет выполнено слияние с мастером?
Росс
55

Все ваши коммиты изменились идентификаторы, так что утечки не действительно расходятся.

Чтобы решить вашу проблему, вам нужно перезаписать удаленную ветку:

git push -f origin experiment

http://git-scm.com/book/ch3-6.html

Объяснение:

Посмотрите, как на этом изображении C3 ставится не как C3 после перебазирования, а как C3 '. Это потому, что это не совсем C3, но в нем есть все изменения кода.

Rebase

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

расходиться и git push

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

Просмотрите ссылку вверху и найдите «git push --force». Вы увидите более подробное объяснение.

миморалея
источник
3
Ага. Думаю, это решает проблему. Но принудительный толчок может не работать, когда вы работаете в команде, когда ваш толчок может перезаписать любую недавнюю работу, продвинутую другими. Я прав?
Hari Krishna Ganji
Это может не дать желаемого эффекта. Перед выполнением перебазирования убедитесь, что вы объединяете свои изменения «быстро вперед».
mimoralea
1

Я добился успеха с отклонением rebase для толчка, выполнив следующие действия:

git checkout mybranch
git pull
git push origin mybranch

Тяга разрешила расхождение.

ПЕРЕД тянуть

Your branch and 'origin/mybranch' have diverged,
and have 2 and 1 different commit(s) each, respectively.

PULL выход

Слияние выполнено рекурсивно. mypath / myfile.py | 12 +++++++++++ - 1 файл изменен, 11 вставок (+), 1 удалений (-)

ПОСЛЕ тяги

Ваша ветка опережает origin / mybranch на 3 коммита.

ПОСЛЕ НАЖАТИЯ

mybranch находится на 3 перед веткой, у него все еще есть сообщение слияния открытого запроса на вытягивание, добавленное в историю коммитов Слияние ветки mybranch of remote в mybranch

Я предполагаю, что это, вероятно, то, что делает принудительный толчок, и я не проверял.

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

ноль
источник
1

Это можно исправить без принудительного толчка, переустановив целевую ветвь в текущую локальную ветвь, переключившись на целевую ветку, а затем переустановив локальную ветку в целевую. Это не расходится, так как коммиты, которые могут отсутствовать, добавляются и их больше не нужно создавать. Пример для более простого объяснения:

  1. основная ветка - развитие
  2. Вы проверяете новую функцию ветки / Making_stuff
  3. Член команды подталкивает к разработке нового обязательства

Если вы НЕ обновляли свою ветку разработки, то «git checkout develop» && «git rebase feature / doing_stuff» будет работать правильно, поскольку с момента оформления заказа не было добавлено никаких коммитов. Однако, если вы проверили разработку и сняли новую фиксацию, вы увидите это расхождение, если попытаетесь выполнить перебазирование из-за появления новой фиксации. Простое исправление без принудительного нажатия (обычно не очень хорошая идея в командной среде):

  1. функция проверки git / do_stuff
  2. git rebase разработать
  3. git checkout разработать
  4. git функция перебазирования / do_stuff

Перебазирование с шага 2 переносит недостающую фиксацию в функцию / Making_stuff, поэтому, когда наступает шаг 4, она актуальна и не требует создания новой фиксации для изменения.

Это решение, которое я знаю, работает, потому что я только что столкнулся с этим и выполнил описанные выше шаги, чтобы успешно протолкнуть разработку без принуждения. Я работаю в команде из более чем 50 разработчиков, поэтому мне запрещено принудительно запускать что-либо, кроме моих собственных веток тестирования, поэтому мне пришлось найти решение.

Крис
источник