Если нажать коммят на сервер, а затем переписать , что совершить локально (с git reset, git rebase, git filter-branchили любую другую историю манипуляции), а затем толкнули , что переписанные фиксации обратно на сервер, вы завинчивать никого , кто тянул. Вот пример; скажем, вы зафиксировали A и отправили его на сервер.
- * - * - A <- master
- * - * - A <- origin / master
Теперь вы решаете переписать A, как вы упомянули, сбросив и повторно зафиксировав. Обратите внимание, что в результате остается болтающаяся фиксация A, которая в конечном итоге будет удалена сборщиком мусора, так как она недоступна.
- * - * - А
\
A '<- мастер
- * - * - A <- origin / master
Если кто-то другой, скажем, Фред, отключается masterот сервера, пока вы это делаете, у него будет ссылка на A, с которой он может начать работать:
- * - * - A '<- master
- * - * - A <- origin / master
- * - * - AB <- fred / master
Теперь, если бы вы могли подтолкнуть свой A 'к origin / master, что привело бы к созданию не-быстрой перемотки вперед, у него не было бы A в его истории. Так что, если бы Фред снова попытался потянуть, ему внезапно пришлось бы выполнить слияние, и он повторно представил бы фиксацию A:
- * - * - A '<- master
- * - * - A <- origin / master
- * - * - AB- \
\ * <- фред / мастер
А '- /
Если Фред это заметит, он сможет выполнить перебазирование, что предотвратит повторное появление коммита A. Но он должен это заметить и не забыть сделать это; и если у вас есть более одного человека, который вытащил A, им всем придется перебазировать, чтобы избежать дополнительной фиксации A в дереве.
Таким образом, как правило, не рекомендуется изменять историю репо, из которого извлекают другие люди. Если, однако, вы знаете, что никто другой не использует это репо (например, это ваше собственное частное репо, или у вас есть только один другой разработчик, работающий над проектом, с которым вы можете легко координировать свои действия), то вы можете принудительно обновить, запустив:
git push -f
или
git push origin +master
Они оба проигнорируют проверку на отсутствие быстрой перемотки вперед и обновят то, что находится на сервере, до вашей новой ревизии A ', отказавшись от ревизии A, так что в конечном итоге она будет собрана для мусора.
Возможно, принудительное нажатие полностью отключено с помощью receive.denyNonFastForwardsпараметра конфигурации. Эта опция включена по умолчанию для общих репозиториев. В этом случае, если вы действительно действительно хотите принудительно выполнить push, лучший вариант - удалить ветку и воссоздать ее с помощью git push origin :master; git push origin master:master. Однако denyNonFastForwardsопция включена по причине, описанной выше; в общем репозитории, это означает, что теперь каждый, кто его использует, должен убедиться, что они перебазируются на новую историю.
В общем репозитории, как правило, лучше просто размещать новые коммиты сверху, чтобы исправить любую вашу проблему; вы можете использовать git revertдля создания коммитов, которые отменят изменения предыдущих коммитов.