Как тянуть после принудительного нажатия git?

Предположим, что я извлекаю изменения из репозитория git. Затем автор силы репо подталкивает к центральному репо. Теперь я не могу потянуть, так как история переписана.

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

Я знаю, что это плохой рабочий процесс git, но иногда вы не можете этого избежать.

Ответы

Ответ 1

Отбрасывание локальных изменений

Если вы хотите отменить свою работу, fetch и reset. Например, если у вас есть удаленный с именем origin и веткой с именем master:

$ git fetch origin
$ git reset --hard origin/master # Destroys your work

Сохранение локальных изменений

Если вы не хотите выбрасывать свою работу, вам нужно будет сделать git rebase --onto. Предположим, что старый origin выглядит так:

A ---> B ---> C
              ^
              origin/master

И у вас есть это:

A ---> B ---> C ---> X ---> Y ---> Z
              ^                    ^
              |                    master
              origin/master

Теперь восходящие изменения меняют вещи:

A ---> B ---> C ---> X ---> Y ---> Z
 \                                 ^
  ---> B'---> C'                   master
              ^          
              origin/master

Вам нужно будет запустить git rebase --onto origin/master <C> master, где <C> - это SHA-1 старой ветки origin/master, предшествующей изменениям восходящего потока. Это дает вам следующее:

A ---> B ---> C ---> X ---> Y ---> Z
 \
  ---> B'---> C'---> X'---> Y'---> Z'
              ^                    ^
              |                    master
              origin/master

Обратите внимание, что теперь B, C, X, Y и Z "недоступны". В конечном итоге они будут удалены из вашего хранилища на Git. Тем временем (90 дней) Git сохранит копию в рефлоге, если окажется, что вы допустили ошибку.

Ошибки фиксации

Если вы git reset или git rebase ошибаетесь и случайно потеряете некоторые локальные изменения, вы можете найти изменения в рефлоге.

В комментариях пользователь предлагает git reflog expire с --expire=now, но НЕ ЗАПУСТИТЬ ЭТУ КОМАНДУ, потому что это будет DESTROY вашей защитной сетью. Вся цель иметь reflog заключается в том, что Git иногда сохраняет вашу шею, когда вы запускаете неправильную команду.

В принципе, эта команда будет немедленно уничтожать B, C, X, Y и Z в приведенных выше примерах, чтобы вы не могли их вернуть. Нет никакой реальной выгоды для запуска этой команды, за исключением того, что она может сэкономить немного места на диске, но Git уже очистит данные через 90 дней, чтобы это преимущество было недолгим.