Локально Git самодостаточен, но команда синхронизируется через удалённый репозиторий — общую копию проекта на сервере (GitHub, GitLab, Bitbucket). Три команды — push, pull, fetch — весь трафик между вами и сервером. Здесь же живут и главные страхи новичка: «push отклонён» и «я затёр чужую работу». Разберём так, чтобы страхов не осталось.
origin и отслеживаемые ветки
При git clone адрес сервера сохраняется под именем origin — это просто псевдоним URL (серверов может быть и несколько, но обычно один). Локальная ветка отслеживает (tracks) одноимённую серверную: main знает про origin/main, и git status сообщает расхождение: «ваша ветка отстаёт на 2 коммита».
Важная деталь: origin/main — это локальная копия серверного состояния, снятая при последней синхронизации. Между синхронизациями она устаревает — Git не ходит в сеть сам.
git push -u origin fix-cart # первый push новой ветки: -u связывает её с серверной
git push # дальше просто push
fetch и pull: посмотреть или забрать
git fetch— скачать новое с сервера, не трогая ваши файлы: обновляются только копииorigin/*. После этого можно спокойно посмотреть, что принесли коллеги:git log main..origin/main.git pull= fetch + слияниеorigin/mainв вашу ветку. Файлы обновляются сразу.
Pull — повседневность, fetch — аккуратность: когда хочется сначала увидеть чужие изменения, а потом решать. Полезная настройка git pull --rebase (или pull.rebase=true в конфиге) переносит ваши локальные коммиты поверх свежих серверных вместо создания мелких merge-коммитов «Merge branch main» — история заметно чище; почему это работает — в статье про rebase.
«Push отклонён»: что происходит и что делать
! [rejected] main -> main (fetch first)
Это не поломка, а защита: на сервере есть коммиты, которых нет у вас (коллега успел запушить). Git отказывается затирать их вашей версией истории. Лечение штатное:
git pull # забрать чужое и объединить (возможен конфликт — решается как обычно)
git push # теперь уходит
Чего делать не надо — git push --force в общую ветку: он перезаписывает серверную историю вашей, и чужие коммиты исчезают. Force-push легитимен в одном случае: ваша личная ветка, историю которой вы сознательно переписали перед ревью (и лучше в форме --force-with-lease — она откажется перетирать то, чего вы не видели). В main/develop force-push обычно запрещён настройками сервера — и это правильно.
Ежедневный цикл
Типичный день с удалённым репозиторием:
git switch main && git pull # утро: свежий main
git switch -c feature-export # ветка под задачу
# ...работа, коммиты...
git push -u origin feature-export # отправить ветку
# дальше — pull request, ревью и слияние на сервере
git switch main && git pull # после вливания: обновиться
git branch -d feature-export # прибрать ветку
Единственная привычка, которая делает всё это гладким: начинать от свежего main и пушить ветку рано, не копя неделю локальных коммитов. Ранний push — это ещё и бэкап: сгоревший ноутбук не уносит работу.
Коротко
- origin — псевдоним сервера;
origin/main— локальный снимок серверного состояния, устаревает между синхронизациями. - fetch скачивает не трогая файлы, pull = fetch + слияние.
pull --rebaseдержит историю чистой. - «Push rejected» = на сервере есть новое: pull, затем push. Это защита, а не ошибка.
- Force-push — только в свою ветку и лучше
--force-with-lease; в общие ветки — никогда. - Ритм: от свежего main, ветка на задачу, ранний push.
Что почитать дальше
- Pull request и код-ревью — что происходит с веткой на сервере.
- Ветки и слияние — предыдущая тема цикла.
- Отмена и спасение — если что-то всё-таки пошло не так.