git fetch - половина того, что делает git pull. Только половина:
«скачать», без «слить». Это её главное достоинство.
Что физически происходит
git fetch origin
- Подключается к origin (по SSH или HTTPS).
- Узнаёт у remote список refs и их SHA.
- Скачивает все коммиты, которых нет локально, в
.git/objects/. - Обновляет
refs/remotes/origin/<branch>- это «remote-tracking branches».
Локальные ветки не меняются. main, feature/x, HEAD - всё
на месте. Меняются только origin/main, origin/feature/x - это
отдельные refs, которые отслеживают состояние remote.
git log main..origin/main # коммиты, которые пришли, но не слиты
git diff main origin/main # что изменится при merge
Это даёт паузу между «получил данные» и «применил». Можно посмотреть, что прилетело, прежде чем mergить.
Когда нужен fetch вместо pull
- Сложные слияния. Перед mergом хочется глянуть, что прилетело.
- Несколько remote. При работе через fork (см. upstream-vs-origin)
обычно
git fetch upstream, потом отдельно решать, что делать. - CI/скрипты. Скрипт сравнения версий: fetch, потом diff.
- Просто посмотреть. «Кто что запушил за сегодня» - fetch не меняет рабочий каталог.
Полезные флаги
git fetch --all # все remote сразу
git fetch --prune # удалить локальные refs веток,
# которых уже нет на remote
git fetch --tags # включая теги
git fetch origin main # только конкретную ветку
git fetch origin pull/123/head:pr-123 # GitHub PR как локальная ветка
--prune особенно полезен в долго живущем клоне: ветки в команде
создаются и удаляются, без --prune локальный список
origin/<branches> распухает мёртвыми ссылками. Можно настроить
раз и навсегда: git config --global fetch.prune true.
Что делать после fetch
Типичные варианты:
# Догнать локальную main без mergе
git fetch origin
git switch main
git merge --ff-only origin/main
# Альтернатива: rebase своей фичи поверх свежей main
git fetch origin
git switch feat/x
git rebase origin/main
# Просто посмотреть, что нового
git fetch origin
git log main..origin/main --oneline
Подводные камни
git fetchничего не показывает в working tree. Если ожидаешь увидеть новые файлы - нет, нужно ещё merge или rebase.- Без
--pruneостаются «мёртвые» ветки вorigin/. Через год их бывают десятки. - В CI с shallow clone (
--depth 1) fetch ведёт себя ограниченно: история не догружается, нужно--unshallowили--deepen N.