# git push _Удалённые репозитории · GitLab Knowledge Base_ **TL;DR:** Отправляет локальные коммиты в удалённый репозиторий и обновляет там ветку. Если remote получил коммиты от кого-то другого после твоего последнего pull - push откажется, пока не синхронизируешься. `git push` синхронизирует локальные ветки с удалённым репозиторием. Это вторая половина пары «pull/push», без неё работа никому больше не видна. ## Базовая форма ```bash 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` без аргументов будет знать, куда идти. ## Что физически происходит 1. Git собирает packfile из коммитов, которых нет на remote. 2. Передаёт по сети (через SSH или HTTPS). 3. Просит remote передвинуть его ref `refs/heads/` на новый SHA. 4. 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. ```bash git push --force # опасный git push --force-with-lease # безопасный ``` `--force` слепо переписывает remote ветку, даже если кто-то другой только что туда что-то запушил - его коммиты молча пропадут. `--force-with-lease` сначала проверяет: совпадает ли SHA remote ветки с тем, что Git видел в последний раз? Если нет - кто-то успел запушить, force отменяется. Это и есть тот вариант, который стоит использовать всегда вместо `--force`. В `main`/`master` force-push обычно запрещён branch-protection правилами. Это правильно - общая история не должна переписываться. ## Удаление удалённой ветки ```bash git push origin --delete feature # или эквивалентно: git push origin :feature ``` Второй вариант - старый синтаксис, видишь в скриптах. Семантика: «запушить пустоту в feature», то есть удалить. ## Подводные камни - `git push` без `-u` при первой отправке требует явный `origin `. Без этого Git не знает, куда пушить. - Если remote называется не `origin` (например, `upstream`) - это надо указать явно или настроить tracking. - `push` отправляет **только указанную ветку**, не все локальные. Чтобы отправить теги отдельно - `git push --tags` или `git push origin `. ## Команды ```bash git push -u origin feature ``` Запушить и установить tracking ```bash git push --force-with-lease ``` Безопасный force-push (откажется, если remote ушёл вперёд) ```bash git push origin --delete feature ``` Удалить удалённую ветку ```bash git push --tags ``` Отправить все локальные теги ## См. также - [git pull](/courses/git/kb/pull.md) - [Ветка (branch)](/courses/git/kb/branch.md) - [git merge](/courses/git/kb/merge.md)