Ошибка rejected — non-fast-forward при git push
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/ivan/todo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.На сервере есть коммиты, которых нет у вас: кто-то отправил свои, или вы сами отправили их с другого компьютера. Сервер не принимает отправку, которая затёрла бы эти коммиты. Решение — сначала забрать их, потом отправить свои:
git pull
git pushВариант той же ошибки — ! [rejected] main -> main (fetch first): Git ещё даже не скачивал новые коммиты с сервера. Решение то же.
git pull просит выбрать способ: divergent branches
В свежих версиях Git git pull может остановиться:
hint: You have divergent branches and need to specify how to reconcile them.
fatal: Need to specify how to reconcile divergent branches.Новые коммиты есть и у вас, и на сервере, и Git просит один раз решить, как их объединять. Самый понятный вариант — слиянием:
git config --global pull.rebase false
git pull
git pushgit pull создаст коммит слияния и откроет редактор с сообщением — сохраните и закройте его. Если вместо слияния вы хотите переносить свои коммиты поверх чужих (прямая история без коммитов слияния), задайте pull.rebase true — но сначала прочитайте об rebase в уроке Работа в команде.
Если при git pull возник конфликт — решите его, как в справке Как решить конфликт, и затем git push.
refusing to merge unrelated histories
fatal: refusing to merge unrelated historiesТак бывает с первой отправкой: репозиторий на сервере создали с файлом README или лицензией, и у него свой первый коммит, никак не связанный с вашей историей. Если уверены, что объединить нужно именно эти два репозитория, разрешите слияние один раз:
git pull origin main --allow-unrelated-histories
git push -u origin mainЕсли в обоих есть файл с одним именем (часто README.md), будет конфликт — решите его обычным способом.
Нельзя: принудительная отправка
git push --force «решает» ошибку, заменяя ветку на сервере вашей — и все чужие коммиты, которых у вас нет, пропадают с сервера. В общую ветку так отправлять нельзя. Принудительная отправка нужна только после осознанного переписывания своей ветки (--amend, rebase), и тогда безопаснее git push --force-with-lease.
Подводные камни
- Подсказка
use 'git pull'послеgit commit --amendотправленного коммита — ловушка:pullсольёт старую и новую версии коммита. Что делать в этом случае — в справке Как изменить сообщение коммита. - На защищённую ветку (обычно
main) хостинг может не принимать прямые отправки вовсе — сообщение тогда другое, про защиту ветки. Отправьте ветку задачи и откройте pull request. git statusпослеgit fetchзаранее показывает, разошлись ли ветки:Your branch and 'origin/main' have diverged.