linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it works
  • Уроки
  • База знаний
  • Собеседование
home/git/kb/Удалённые репозитории/force-push

kb/remote ── Удалённые репозитории ── intermediate

Force push

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

view as markdownaka: git-push-force, force-with-lease

Обычный push требует fast-forward: удалённая ветка должна быть предком твоей локальной. Это защита от случайной потери чужих коммитов.

Иногда защиту нужно обойти - например, после локального rebase, amend или interactive rebase (interactive-rebase) SHA коммитов изменились, и обычный push отказывается:

! [rejected]  feat -> feat (non-fast-forward)

Здесь приходит force-push.

--force: тупой и опасный

bash
git push --force origin feat

Что делает: говорит remote'у «забудь, что у тебя там было, поставь ровно мою историю». Если кто-то другой запушил коммит между твоим последним fetch и push'ем - его коммит исчезает. Не сразу заметишь: его клон ещё содержит этот коммит, но в общем remote'е его уже нет.

Это и есть «forge force-push накосячил» - типичная катастрофа в командной работе.

--force-with-lease: безопасный

bash
git push --force-with-lease origin feat

Что делает: говорит remote'у «перезапиши ветку, но только если её текущий SHA = тому, что я последний раз видел через fetch». Если SHA отличается - значит кто-то запушил после тебя, и force отменяется.

! [rejected]  feat -> feat (stale info)

В этом случае: сделай git fetch, посмотри, что прилетело, реши что с этим делать (обычно rebase своих коммитов поверх новых), и повтори force-with-lease.

Правило: никогда --force, всегда --force-with-lease. Можно настроить алиас, чтобы пальцы автоматически шли в правильную сторону:

bash
git config --global alias.pushf 'push --force-with-lease'

Или ещё параноидальнее: с явной проверкой SHA, который ты ожидаешь:

bash
git push --force-with-lease=feat:abc123 origin feat

Когда force нужен

  • После rebase своей feature-ветки. Это штатный сценарий.
  • После amend последнего коммита запушенной feature-ветки.
  • После interactive rebase для очистки истории перед PR.

Все три - только на ветках, которые видишь ты один. На main, master, develop force-push запрещён branch-protection правилами форджа.

Когда force НЕ нужен

  • «Запушил с ошибкой в commit message» - обычно проще оставить, или исправить новым коммитом. Force не за этим.
    • «Хочу удалить из истории секрет» - недостаточно. См. git-filter-repo, плюс ротируй секрет в любом случае.
    • «Не разобрался с merge» - нет, делай merge или rebase, не force.

Branch protection: сетка снизу

На GitHub/GitLab у защищённых веток (main, master, release/*) можно включить:

  • Запрет force-push.
  • Запрет прямого push (только через PR).
  • Требование зелёного CI и аппрувов.

Это страховка от человеческой ошибки. Включай её на main всегда, даже в маленьких командах.

Подводные камни

  • Фоновый fetch может обмануть --force-with-lease. Lease без явного SHA сравнивается с твоим remote-tracking ref'ом (refs/remotes/origin/feat). Обычно «давно не fetch'ил» - это хорошо: lease видит старый SHA, не совпадает с реальным remote, push отклоняется со stale info. Опасный сценарий - когда что-то делает fetch без тебя (IDE, watcher, параллельный терминал): remote-tracking ref молча обновляется до свежего чужого SHA, lease совпадает, force проходит и затирает их коммиты. Защита - использовать явный SHA: git push --force-with-lease=feat:<sha>, где <sha> - то, что ты сам видел через git fetch и осознанно решил перезаписать.
  • На некоторых форджах reflog хранится 30+ дней. Если кого-то случайно перезаписали - обычно SHA можно восстановить из reflog форджа или из локального клона коллеги.
  • Force-push ломает чужие watch'и. Если кто-то ребейзится на твою ветку (stacked PRs), force-push заставит его тоже ребейзиться. В stacked-workflow это норма, но предупреждай.

§ команды

bash
git push --force-with-lease

Безопасный force: отказ, если remote ушёл вперёд

bash
git push --force

Тупой force: затирает чужие коммиты молча. ИЗБЕГАТЬ

bash
git config --global alias.pushf 'push --force-with-lease'

Алиас, чтобы пальцы шли в правильную сторону

bash
git fetch && git push --force-with-lease

Свежий lease перед force

§ см. также

  • pushgit pushОтправляет локальные коммиты в удалённый репозиторий и обновляет там ветку. Если remote получил коммиты от кого-то другого после твоего последнего pull - push откажется, пока не синхронизируешься.
  • rebasegit rebaseПереписывает коммиты ветки, делая их потомками другого коммита. Создаёт новые SHA, история становится линейной. Безопасен только для веток, которые ещё никто, кроме автора, не видел.
  • interactive-rebaseInteractive rebase`git rebase -i <base>` открывает редактор со списком коммитов от `<base>` до HEAD, где можно переименовывать, объединять, удалять и переставлять их. Главный инструмент для очистки локальной истории.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки