Git: Как проигнорировать перемотку вперед и вернуть origin [branch] к более раннему коммиту?
Я использовал
git reset --hard dc082bc...вернуться к ветви обратно в требуемое предыдущее состояние из-за некоторых неудачных фиксаций. Это перемотало мой местный филиал в порядке. Тем не менее, я хочу перемотать ветку 'origin' к тому же коммиту, чтобы я мог начать заново. Может кто-нибудь сказать мне, как вернуть исходную ветвь (не master) для этого коммита?
Я пробовал git push origin master, но выдает следующую ошибку
! [отклонено] ветвь -> ветвь (без ускоренной перемотки вперед) ошибка: не удалось отправить некоторые ссылки на "git@github.com:xxx/xxx.git" Чтобы предотвратить потерю истории, обновления без ускоренной пересылки были отклонены Объедините удаленные изменения перед повторным нажатием. Смотрите "Примечание о раздел "Перемотка вперед" в git push --help для деталей.
2 ответа
Ты можешь попробовать git push --force
заставить толчок.
--force
Обычно команда отказывается обновлять удаленную ссылку, которая не является предком локальной ссылки, используемой для ее перезаписи. Этот флаг отключает проверку.
Это может привести к потере коммитов удаленным репозиторием; используйте это с осторожностью.
Так что, если многие люди уже вытащили одну и ту же ветку из источника, это может вызвать проблемы с перебазировкой на их стороне.
Эта операция может быть заблокирована на стороне сервера, как указывает ebneter (в комментариях):
Однако, в зависимости от того, как настроен пульт, это может не сработать
- все мои центральные репозитории настроены сreceive.denyNonFastForwards = true
а такжеreceive.denyDeletes = true
, в этом случае любая такая операция должна быть сделана на удаленном сервере.
Однако в случае с GitHub такие настройки не всегда доступны для пользователя, управляющего его репозиторием GitHub.
Так что если вы git push --force
по ошибке все, что вам осталось, - это открыть дело для поддержки GitHub, чтобы они проверили свои локальные (т.е. "GitHub") рефлоги и посмотрели, могут ли они восстановить старые коммиты.
(Поскольку reflogs являются локальными, как я недавно вспомнил. Поэтому коммиты, которые заменяются новыми во время push --force
только еще видны, если нет git gc
' или же ' git prune
уже на стороне сервера GitHub)
Итак, Marco Ceppi настаивает (в комментариях):
это может действительно испортить локальные репозитории других участников, если вы заставляете толчки - хотя иногда это просто необходимое зло (возможно, мне приходилось делать это два раза в моей жизни с использованием Git)
Чтобы добавить к моему предыдущему ответу, и рассмотреть тот факт, что вынужденный git push
может действительно испортить локальные репозитории других участников, git 1.8.5 (предстоящий 4 квартал 2013 г.) увидит новую опцию:
git push --force-with-lease
Смотрите происхождение этой опции в этой теме:
если что-то случится в
origin
"В ветке, которую вы заставляете или удаляете с тех пор, как выбрали ее для проверки, вы можете потерять работу других людей.Кто-то, кто не знает о решении перемотать и перестроить ветку, может попытаться нажать на ветку между временем, которое вы выбрали, чтобы перебазировать его, и временем, которое вы подтолкнули, чтобы заменить его результатом перебазировки.
Мы можем
make these pushes safer
опционально позволяя пользователю сказать "git push
" этот:Я заставляю / удаляю, исходя из предположения, что значение 'branch' все еще находится в этом объекте.
Если это предположение больше не выполняется, то есть, если что-то случилось с веткой с тех пор, как я начал готовиться к этому пушу, не продолжайте и провалите этот пуш.
Вы можете увидеть полную документацию --force-with-lease
в коммите 28f5d17
--force-with-lease
будет защищать все удаленные ссылки, которые будут обновлены, требуя, чтобы их текущее значение было таким же, как некоторые разумные значения по умолчанию, если не указано иное;На данный момент "некоторое разумное значение по умолчанию" предварительно определено как "значение ветви удаленного отслеживания, которую мы имеем для ссылки на обновляемый удаленный", и это ошибка, если у нас нет такой ветви удаленного отслеживания.
Это объясняет "аренду" часть этого варианта:
"
force-with-lease
Msgstr ": Вы предполагаете, что взяли в аренду аренду рефери, когда выбирали, чтобы решить, какой должна быть перебазированная история, и вы можете откатиться назад, только если аренда не была нарушена.
Это уже проверяется и упоминается в разделе " Что готовит в git.git (Aug 2013, # 07; Wed, 28) ":
Кстати, толчок, который переопределяет обычное "перемотка вперед", был сделан с помощью "
force-with-lease
"Вариант, который готовил вnext
, вот так:
$ git fetch ko next
$ anchor=$(git rev-parse --verify FETCH_HEAD)
$ for remote in ko repo gph github2
do
git push --force-with-lease=refs/heads/next:$anchor $remote next
done
Заметка: " git push --force-with-lease
"научили сообщать, нужно ли форсировать толчок (или быстро пересылать).
Итак, эта команда более подробно представлена в выходных данных git 2.8 (март 2016 г.)
push: исправить отчет о статусе ссылки для
--force-with-lease
--force--with-lease
опция push приводит к менее подробной информации о статусе, чем--force
,
В частности, выходные данные указывают, что ссылка была быстро передана, даже когда она была принудительно обновлена.
Остерегайтесь игнорирования / игнорирования этого параметра, как описано в Git 2.13 (2-й квартал 2017 года).
git reset
&& git push
с принудительной перезаписью
# master commit uid
$ git reset --hard b9e3f7f2f66674901b467183dd81d493e50677f5
# git push branch_name --force
# local master
$ git push origin master --force
# remote master
$ git push origin/master -f