← назад к разделу

Локально 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 и код-ревью — что происходит с веткой на сервере.
  • Ветки и слияние — предыдущая тема цикла.
  • Отмена и спасение — если что-то всё-таки пошло не так.