Как перебазировать сдвинутые ветви, не разрушая дерево?

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

Есть ли способ отправить перебазирование на сервер без дополнительной фиксации «ветки слияния» как его части?

Спасибо!


person stuntboots    schedule 13.02.2020    source источник


Ответы (1)


По сути, Rebase - это операция «скопировать некоторые коммиты, а затем отказаться от старых коммитов в пользу новых и предположительно улучшенных коммитов».

Рассмотрим, например, такую ​​ситуацию:

...--A--B--E--F   <-- master
         \
          C--D--G   <-- feature (HEAD)

Вы завершили работу над своей функцией feature, но по какой-то причине вам пришлось создать две фиксации master, пока вы работали. Так что теперь feature можно было переписать.

Никакая фиксация не может когда-либо измениться, поэтому на самом деле невозможно заменить C новым и улучшенным вариантом, но мы можем сделать новый и улучшенный C' для замены C в любом случае, используя временную ветку или режим Git "отключенной HEAD":

                C'  <-- HEAD
               /
...--A--B--E--F   <-- master
         \
          C--D--G   <-- feature

Фиксация C' выполняет F то же самое, что фиксация C делает B. Старый (и теперь никудышный) C имеет B в качестве своего родителя, в то время как новый улучшенный C' имеет F в качестве своего родителя. Итак, теперь нам нужно скопировать D в новый и улучшенный D', а затем повторить то же самое для G:

                C'--D'--G'  <-- HEAD
               /
...--A--B--E--F   <-- master
         \
          C--D--G   <-- feature

Теперь мы готовы к последней уловке git rebase. Он удаляет имя feature из фиксации G и вместо этого указывает feature на G':

                C'--D'--G'  <-- feature (HEAD)
               /
...--A--B--E--F   <-- master
         \
          C--D--G   [abandoned]

Поскольку мы даже не можем увидеть оставленные коммиты в локальном репозитории на вашем ноутбуке, похоже, что история всегда была такой: вы написали коммит C' на основе F и так далее. Хеш-идентификаторы выглядят случайными; никто, кроме вас, никогда не узнает обо всем этом.

Только ... вы сделали git push коммитов C-D-G или, по крайней мере, некоторые из них, в Bitbucket. У них есть ваши старые и паршивые коммиты, на которые указывает их имя ветки feature. Вы отправляете им свои блестящие новые - git push origin feature - и в конце этого ваш Git вежливо просит их переместить их feature имя, чтобы оно указывало на фиксацию G' вместо G.

Это, конечно, заставит их отказаться от фиксации G в пользу нового и улучшенного G'. Это то, что вы хотите, чтобы они сделали. Но они скажут: Нет, если я сделаю это, я потеряю свою драгоценную фиксацию G!

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

Это можно сделать, добавив --force или --force-with-lease к вашей git push команде. Это превращает вежливый запрос: Пожалуйста, если все в порядке, настройте свой feature на команду: Настройте свою функцию!

Разница между --force и --force-with-lease в том, что последний сначала добавляет проверку безопасности. Вместо того, чтобы просто сказать Установите свое имя feature так, чтобы оно указывало на фиксацию G'!, ваш Git скажет: Я думаю, на основании моей информации, что ваш feature указывает на фиксацию G. Если это так, установите вместо этого указатель на G'. Если нет, дайте мне знать, что я пошутил.

Очевидно, что проверка безопасности обычно хороша, но в ней также нет необходимости, если вы единственный, кто когда-либо помещает новые коммиты в репозиторий на Bitbucket.

person torek    schedule 13.02.2020
comment
Отлично, спасибо @torek! Итак, просто чтобы подтвердить, есть ли недостаток в том, чтобы всегда просто использовать --force-with-lease, даже если я являюсь индивидуальным разработчиком? Похоже, это создаст хорошую привычку, хе-хе. - person stuntboots; 13.02.2020
comment
Вероятно, да. Лично у меня здесь есть вредные привычки (выработанные за 10 с лишним лет ...) :-) - person torek; 13.02.2020