По сути, 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