Git: Как игнорировать ускоренную перемотку вперед и вернуть начало [ветку] до более раннего фиксации?
Я использовал
git reset --hard dc082bc...
, чтобы вернуться к ветки обратно в требуемое предыдущее состояние из-за некоторых плохих коммитов. Это изменило мой тоннель в местном филиале. Тем не менее, я хочу перемотать ветвь на "происхождение" на одну и ту же фиксацию, чтобы я мог начать заново. Может ли кто-нибудь сказать мне, как вернуть ветку происхождения (а не мастер) на эту фиксацию?
Я пробовал git push origin master, но он дает следующую ошибку
! [rejected] branch -> branch (non-fast-forward)
error: failed to push some refs to '[email protected]:xxx/xxx.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the 'Note about
fast-forwards' section of 'git push --help' for details.
Ответы
Ответ 1
Вы можете попробовать git push --force
принудительно нажать.
--force
Обычно команда отказывается обновлять удаленный реф, который не является предком локального ref, используемого для его перезаписывания. Этот флаг отключает проверку.
Это может привести к тому, что удаленный репозиторий потеряет фиксации; используйте его с осторожностью.
Итак, если многие люди уже вытащили одну ветку из источника, это может вызвать некоторые проблемы на их стороне.
Эта операция может быть заблокирована на стороне сервера, например, ebneter указывает (в комментариях):
В зависимости от того, как настроен пульт дистанционного управления, это может не работать - все мои центральные репозитории настроены с receive.denyNonFastForwards = true
и receive.denyDeletes = true
, и в этом случае любая такая операция должна выполняться на удаленном сервере.
Однако в случае GitHub такие настройки недоступны для пользователя, управляющего репо GitHub.
Поэтому, если вы ошибаетесь git push --force
, все, что вам осталось, открытие дела для поддержки GitHub, чтобы проверить их локальные (т.е. "GitHub" ) reflogs и посмотреть, могут ли они восстановить старые коммиты.
(Так как reflogs являются локальными, как будто я недавно был запомнен, поэтому коммиты, которые заменяются новыми во время push --force
, все еще видны, если нет 'git gc
'или' git prune
'уже на стороне сервера GitHub)
Итак Марко Чеппи настаивает (в комментариях):
это может действительно испортить другие участники локальных репозиториев, если вы заставляете толкать - хотя это времена, когда это просто необходимое зло (мне, возможно, приходилось делать это два раза в моей жизни с помощью Git)
Ответ 2
Чтобы добавить в мой предыдущий ответ и устранить тот факт, что принудительный git push
может действительно испортить локальные репозитории других участников, git 1.8. 5 (предстоящий четвертый квартал 2013 г.) появится новая опция:
git push --force-with-lease
См. начало этой опции в этот поток:
, если что-то происходит с "origin
" на ветку, которую вы форсируете или удаляете, поскольку вы ее проверяли, вы можете потерять работу других людей.
Кто-то, кто не знает о решении перемотать и перестроить ветку, может попытаться нажать на ветвь между временем, которое вы выбрали, чтобы переустановить его, и временем, когда вы нажали, чтобы заменить его на результат перезагрузки.
Мы можем make these pushes safer
, необязательно позволяя пользователю сообщать "git push
" следующее:
Я заставляю/удаляю, исходя из предположения, что значение "ветки" все еще находится на этом объекте. Если это предположение больше не выполняется, т.е. Если что-то случилось с веткой, так как я начал готовиться к этому нажатию, пожалуйста, не продолжайте и не пропустите этот шаг.
Вы можете увидеть полную документацию --force-with-lease
в commit 28f5d17
--force-with-lease
будет защищать все удаленные ссылки refs, которые будут обновляться, если их текущее значение будет таким же, как некоторые разумные значения по умолчанию, если не указано иное;
В настоящее время "разумное значение по умолчанию" предварительно определяется как "значение ветки удаленного отслеживания, которую мы имеем для ref обновляемого удаленного", и это ошибка, если у нас нет такого удаленного, отслеживания.
Это объясняет часть "аренды" этого параметра:
"force-with-lease
": Вы предполагаете, что взяли арендную плату в рефери, когда вы взяли решение о том, что такое история с накоплением, и вы можете отступить только в том случае, если аренда не была нарушена.
Это уже тестируется и упоминается в Что готовит в git.git(август 2013, № 07, ср, 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: исправить отчет о статусе ref для --force-with-lease
Опция --force--with-lease
push приводит к менее подробной информации о состоянии, чем --force
.
В частности, вывод указывает, что ссылка была быстро переадресована, даже когда он был обновлен по силе.
Остерегайтесь того, что этот параметр игнорируется/обойден, как объясняется в git 2.13 (Q2 2017).