git push синхронизирует локальные ветки с удалённым репозиторием.
Это вторая половина пары «pull/push», без неё работа никому больше
не видна.
Базовая форма
git push # запушить текущую ветку в её tracking remote
git push origin main # явно: ветку main в remote origin
git push origin feature:main # запушить локальную feature в удалённую main
git push -u origin feature # запушить и установить tracking
Флаг -u (--set-upstream) при первой отправке ветки делает её
«связанной» с удалённой. После этого git push без аргументов
будет знать, куда идти.
Что физически происходит
- Git собирает packfile из коммитов, которых нет на remote.
- Передаёт по сети (через SSH или HTTPS).
- Просит remote передвинуть его ref
refs/heads/<branch>на новый SHA. - Remote проверяет: можно ли fast-forward? Если да - двигает. Если нет - отказывает.
Отказ push'а
Самая частая ошибка:
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the tip of your current branch is behind
Это значит: на remote есть коммиты, которых у тебя нет. Решение -
либо git pull --rebase (затащить чужие коммиты, переписать твои
поверх), либо git pull без rebase (создаст merge-коммит). После
этого push пройдёт.
--force и --force-with-lease
Иногда нужно перезаписать историю на remote - например, после
локального rebase. Для этого force-push.
git push --force # опасный
git push --force-with-lease # безопасный
--force слепо переписывает remote ветку, даже если кто-то другой
только что туда что-то запушил - его коммиты молча пропадут.
--force-with-lease сначала проверяет: совпадает ли SHA remote
ветки с тем, что Git видел в последний раз? Если нет - кто-то
успел запушить, force отменяется. Это и есть тот вариант, который
стоит использовать всегда вместо --force.
В main/master force-push обычно запрещён branch-protection
правилами. Это правильно - общая история не должна переписываться.
Удаление удалённой ветки
git push origin --delete feature
# или эквивалентно:
git push origin :feature
Второй вариант - старый синтаксис, видишь в скриптах. Семантика: «запушить пустоту в feature», то есть удалить.
Подводные камни
git pushбез-uпри первой отправке требует явныйorigin <branch>. Без этого Git не знает, куда пушить.- Если remote называется не
origin(например,upstream) - это надо указать явно или настроить tracking.
- Если remote называется не
pushотправляет только указанную ветку, не все локальные. Чтобы отправить теги отдельно -git push --tagsилиgit push origin <tag>.