Тур по Git
Работа с удалёнными репозиториями / Урок 4.8

Обработка отклонённых push-запросов

Когда вы пытаетесь выполнить push, а кто-то другой уже отправил новые коммиты в ту же ветку, Git отклонит ваш push. Это одна из самых распространённых ситуаций при совместной работе — и она легко решается.

Почему push отклоняется

Git требует, чтобы ваш push был fast-forward — то есть история ветки в удалённом репозитории должна быть прямым предком вашей локальной ветки. Если в удалённом репозитории есть коммиты, которых у вас нет, push перезаписал бы их.

Ваша локальная:  A --- B --- C  (main)
Удалённая:       A --- B --- D  (origin/main)

Вы пытаетесь отправить C, но в удалённом репозитории уже есть D. Git отказывает:

! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally.

Решение: pull, затем push

Стандартный рабочий процесс прост:

  1. Pull — получить удалённые изменения
  2. Разрешить конфликты, если они есть
  3. Push снова
git pull origin main
# разрешите конфликты, если нужно
git push origin main

Что происходит во время pull

Когда вы делаете pull, Git сливает удалённые изменения в вашу ветку:

До pull:
  локальная:   A --- B --- C  (main)
  удалённая:   A --- B --- D  (origin/main)

После pull (merge):
  локальная:   A --- B --- C --- M  (main)
                       \         /
                        --- D ---

Теперь ваша ветка включает и C, и D, и push завершится успешно.

Pull с rebase (более чистая история)

Вместо создания коммита слияния можно перебазировать вашу работу поверх удалённых изменений:

git pull --rebase origin main

Это воспроизводит ваши коммиты после коммитов удалённого репозитория:

До:
  локальная:   A --- B --- C  (main)
  удалённая:   A --- B --- D  (origin/main)

После pull --rebase:
  локальная:   A --- B --- D --- C'  (main)

Результат — чистая линейная история без коммита слияния.

Попробуйте!

Смоделируйте и разрешите отклонение push:

  1. Проверьте текущее состояние: git log --oneline
  2. Попробуйте отправить (может не получиться, если удалённый репозиторий впереди): git push origin main
  3. Если отклонено, сначала получите изменения: git pull origin main
  4. Проверьте, что слияние прошло успешно: git log --oneline --graph
  5. Отправьте снова: git push origin main
  6. Убедитесь в успехе: git log --oneline

Как избежать конфликтов при push

  • Делайте pull перед началом работы — Начинайте каждую сессию с git pull
  • Отправляйте чаще — Небольшие, частые push уменьшают вероятность конфликтов
  • Общайтесь — Сообщайте коллегам, когда работаете с общими файлами
  • Используйте feature-ветки — Работайте в отдельных ветках, чтобы не мешать друг другу

Никогда не используйте force push (если не знаете, что делаете)

Может возникнуть соблазн использовать git push --force. Это перезаписывает историю удалённого репозитория и может уничтожить работу ваших коллег. Используйте только для веток, где вы единственный участник, и даже тогда предпочитайте --force-with-lease, который проверяет, что удалённый репозиторий не изменился с момента последнего fetch.

🎯

Цель

Обработайте отклонение push, сначала сделав pull, затем push

Terminal
$

No commits yet. Run `git init` and create your first commit.