Как перебазировать задвинутые ветви без разрушения дерева? - PullRequest
0 голосов
/ 13 февраля 2020

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

Есть ли способ сделать pu sh rebase на сервер, не имея при этом дополнительной фиксации "Merge branch"? 1003 *

Спасибо!

1 Ответ

1 голос
/ 13 февраля 2020

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

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

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

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

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

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

Commit C' делает для фиксации F, что commit 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]

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

Только ... вы сделали 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.

...