Иконка подарка

Весенняя распродажа! Скидка 15% по промокоду

до 01.04.2026

Получение изменений в Git с помощью git fetch

27 марта 2026
Автор

Олег Марков

Введение

Команда git fetch часто остается недооцененной, хотя именно она лежит в основе безопасной работы с удаленными репозиториями. С ее помощью вы получаете все новые коммиты и ссылки с сервера, но не меняете свое текущее состояние рабочей ветки. Это позволяет спокойно изучить изменения, сравнить их со своей работой и уже потом решать, как их интегрировать.

Смотрите, я покажу вам, как git fetch помогает отделить получение данных от слияния и почему опытные разработчики используют его ежедневно. Мы разберем не только базовый синтаксис, но и полезные флаги, типичные сценарии использования, а также то, как git fetch связан с ветками, remote-tracking ветками и тегами.

Что делает git fetch на самом деле

Локальный репозиторий и remote-tracking ветки

Чтобы понимать, что делает git fetch, важно разобраться с термином "remote-tracking ветка".

Когда вы клонируете репозиторий, Git создает:

  • ваши обычные локальные ветки (например, main или develop)
  • специальные ветки вида origin/main, origin/develop и т.д.

Ветки origin/main, origin/feature-x и подобные называются remote-tracking ветками. Они не для прямой разработки, а для хранения состояния веток на удаленном репозитории (обычно origin). Это как локальный "слепок" удаленных веток на момент последнего обновления.

Теперь главное: git fetch обновляет именно эти remote-tracking ветки и связанные с ними объекты (коммиты, теги), но не трогает ваши локальные ветки и рабочие файлы.

Краткое определение git fetch

Если выразить суть git fetch в одном предложении:

  • git fetch скачивает из удаленного репозитория новые объекты (коммиты, ветки, теги) и обновляет ссылки origin/*, но не изменяет вашу текущую ветку и файлы в рабочем каталоге.

Это ключевое отличие от git pull, который помимо fetch сразу же пытается слить изменения в вашу текущую ветку.

Базовое использование git fetch

Самый простой вариант

Давайте разберемся на самом простом примере. Вы сидите в ветке main и хотите получить все свежие изменения с сервера origin, но пока не готовы их сливать:

# Получаем все обновления из удаленного репозитория origin
git fetch origin

Что произойдет:

  • Git обратится к серверу origin
  • скачает все новые коммиты, которых нет у вас локально
  • обновит remote-tracking ветки, например:
    • origin/main
    • origin/develop
    • origin/feature/login
  • ваша локальная ветка main останется на своем текущем коммите
  • файлы на диске не изменятся

Чтобы увидеть разницу между вашей веткой main и обновленной origin/main, вы можете выполнить:

# Показываем разницу между локальной веткой main и удаленной origin/main
git diff main..origin/main

Комментарии:

  • так вы увидите, какие изменения есть на сервере, но еще не применены у вас
  • ничего не сливается автоматически, вы просто смотрите разницу

git fetch без указания remote

Часто вы увидите такую форму:

# Эквивалентно git fetch origin если origin — remote по умолчанию
git fetch

Здесь Git использует удаленный репозиторий по умолчанию (обычно origin). Так можно писать, если у вас не несколько удаленных репозиториев, а один основной.

Просмотр обновленных веток после fetch

После выполнения git fetch вам полезно посмотреть, какие ветки обновились. Вот простой способ:

# Показываем локальные и remote-tracking ветки
git branch -vv

Комментарии:

  • флаг -vv показывает, к какой remote-tracking ветке привязана локальная ветка и какой у нее последний коммит
  • вы увидите, отстает ли ваша локальная ветка от удаленной (например, на несколько коммитов)

Отличие git fetch от git pull

Концептуальная разница

Теперь давайте разберемся, в чем практическое отличие git fetch и git pull.

  • git fetch:

    • только скачивает изменения и обновляет origin/*
    • ваша текущая ветка не меняется
    • рабочие файлы не меняются
  • git pull:

    • сначала делает git fetch
    • затем автоматически выполняет слияние (merge) или перемотку (fast-forward) в текущую ветку
    • может изменить ваши файлы и историю ветки

Фактически:

git pull

эквивалентно:

git fetch
git merge origin/ТЕКУЩАЯ_ВЕТКА    # или git rebase в зависимости от настроек

Почему многие предпочитают сначала git fetch

Покажу вам типичный рабочий процесс в командах, где ценят контроль над историей:

# 1. Получаем свежие данные с сервера
git fetch

# 2. Смотрим, что именно изменилось
git log HEAD..origin/main --oneline

# 3. Сравниваем код до слияния
git diff HEAD..origin/main

# 4. Только после анализа — сливаем или перематываем
git merge origin/main     # или git rebase origin/main

Такой подход позволяет:

  • заранее увидеть, какие коммиты придут в вашу ветку
  • избежать неожиданного мерджа и конфликтов "вслепую"
  • принять осознанное решение — делать merge, rebase или пока ничего не трогать

Частые сценарии использования git fetch

Получить все изменения и обновить текущую ветку

Самый распространенный сценарий: вы хотите быть в актуальном состоянии относительно origin/main.

Порядок действий:

# Находимся в ветке main
git checkout main

# 1. Получаем изменения
git fetch origin

# 2. Обновляем локальную ветку main до origin/main
git merge origin/main
# или если хотите "идеальную" прямую историю:
# git rebase origin/main

Комментарии:

  • после git fetch у вас есть обновленная origin/main
  • merge добавит новый merge-коммит (если не fast-forward)
  • rebase перепишет ваши локальные коммиты поверх origin/main

Получение изменений только для одной ветки

Иногда вам не нужны все ветки, а только одна конкретная. Для этого можно использовать более точную форму:

# Получаем только изменения ветки main из origin
git fetch origin main

Что происходит:

  • Git скачает только те объекты, которые нужны для обновления origin/main
  • остальные ветки в origin останутся не обновленными в вашем локальном репозитории

Получение всех веток и тегов

Если вы хотите полностью "синхронизировать" локальную копию с удаленным репозиторием (по структуре ссылок), есть смысл получить и ветки, и теги:

# Получаем все ветки и все теги
git fetch --all --tags

Комментарии:

  • --all — пройтись по всем настроенным удаленным репозиториям (origin, upstream и т.д.)
  • --tags — дополнительно получить все теги, даже если они не достигались по ссылкам веток

Разбор ключевых опций git fetch

--all

# Получаем обновления со всех удаленных репозиториев
git fetch --all

Когда это полезно:

  • у вас настроено несколько удаленных:
    • origin — ваш форк
    • upstream — оригинальный репозиторий
  • вы хотите сразу подтянуть изменения отовсюду

Git последовательно выполнит fetch для каждого remote.

--prune

Со временем некоторые ветки на сервере удаляются, а у вас при этом остаются старые записи origin/branch-old. Это захламляет список веток и мешает ориентироваться.

Опция --prune решает эту проблему:

# Получаем изменения и удаляем локальные remote-tracking ветки, которых уже нет на сервере
git fetch --prune
# Короткая форма
git fetch -p

Что делает --prune:

  • сравнивает список веток на сервере и ваши remote-tracking ветки
  • удаляет те origin/ветка, для которых нет соответствующей ветки на сервере

Вы можете включить prune по умолчанию:

# Включаем автоматический prune при каждом fetch для всех репозиториев
git config --global fetch.prune true

--tags и --no-tags

По умолчанию git fetch загружает только те теги, на которые есть ссылки из веток или явно запрашиваемых объектов. Если вам нужно забрать все теги, используйте:

# Получаем все теги с сервера origin
git fetch origin --tags

Если наоборот, вы не хотите получать теги в конкретном вызове:

git fetch origin --no-tags

Это может быть полезно в больших репозиториях с огромным количеством тегов, если вы их не используете.

--depth (shallow fetch)

Иногда нужен "облегченный" репозиторий — например, для CI/CD, где важны только последние несколько коммитов, а не вся история.

Здесь помогает параметр --depth:

# Получаем только последние 20 коммитов ветки main
git fetch origin main --depth=20

Комментарии:

  • такой репозиторий называется shallow (поверхностный)
  • в нем нет всей истории, поэтому некоторые команды Git будут работать ограниченно

Расширить shallow-репозиторий можно, увеличив глубину:

# Догружаем еще историю
git fetch origin --depth=100

или полностью убрав ограничение:

# Делаем репозиторий "полным" догружая всю историю
git fetch origin --unshallow

--dry-run

Если вы хотите понять, что изменится после fetch, но пока ничего не скачивать, используйте:

# Показываем что было бы обновлено, но не скачиваем
git fetch --dry-run

Git выведет список веток, которые будут обновлены, но не изменит локальный репозиторий. Это удобно, чтобы перед важным обновлением понять масштаб изменений.

Работа с несколькими удаленными репозиториями

Настройка нескольких remote

Частый сценарий — работа с форком. У вас есть:

  • origin — ваш форк
  • upstream — оригинальный репозиторий

Добавить второй remote можно так:

# Добавляем новый удаленный репозиторий с именем upstream
git remote add upstream https://github.com/ORIGINAL/PROJECT.git

Теперь, чтобы получить изменения из оригинального репозитория, используйте:

# Получаем изменения из upstream но не из origin
git fetch upstream

Remote-tracking ветки будут иметь вид:

  • upstream/main
  • upstream/develop
  • и т.д.

Теперь вы увидите два набора remote-tracking веток: origin/ и upstream/.

Обновление форка через git fetch

Покажу вам типичный процесс обновления форка:

# 1. Получаем изменения из оригинального репозитория
git fetch upstream

# 2. Переходим на локальную ветку main
git checkout main

# 3. Сливаем изменения из upstream/main в наш main
git merge upstream/main
# или:
# git rebase upstream/main

# 4. Отправляем обновленную ветку в свой форк на GitHub
git push origin main

Комментарии:

  • git fetch upstream ничего не меняет в вашем origin
  • вы явно выбираете, какие изменения из upstream применять

Как git fetch взаимодействует с ветками

Локальные и remote-tracking ветки

Давайте посмотрим на связку локальной ветки и remote-tracking ветки на примере:

# Находимся в локальной ветке main
git checkout main

# Смотрим подробную информацию
git branch -vv

Вы увидите примерно такую строку:

* main 1234abc [origin/main] Some commit message

Комментарии:

  • main — ваша локальная ветка
  • origin/main — remote-tracking ветка, за которой "следит" main
  • это значит, что git pull в этой ветке будет получать изменения именно из origin/main

После git fetch origin origin/main обновится, а main останется прежней. Разницу между ними легко посмотреть:

# Показывает список коммитов которых еще нет в локальной ветке main
git log main..origin/main --oneline

Ссылка FETCH_HEAD

После выполнения git fetch Git создает (или обновляет) специальную ссылку FETCH_HEAD. Она указывает на последние полученные коммиты.

Например:

# Получаем изменения
git fetch origin main

# Сливаем только что полученные изменения не ссылаясь явно на origin/main
git merge FETCH_HEAD

Комментарии:

  • FETCH_HEAD удобно использовать в скриптах
  • чаще всего в интерактивной работе разработчики предпочитают явно писать origin/main, так понятнее

git fetch и теги

Получение отдельных тегов

Если вам нужен конкретный тег с сервера, вы можете получить его так:

# Получаем конкретный тег v1.2.0 из origin
git fetch origin tag v1.2.0

Комментарии:

  • это скачает только указанный тег и связанные с ним объекты
  • удобно, если вам не нужно подтягивать все теги

Обновление всех тегов

Если вам нужны все теги, но вы не хотите обновлять ветки, можно сделать:

# Получаем только теги
git fetch origin --tags

или вместе с остальными изменениями:

# Получаем все ветки и теги
git fetch origin --tags

После этого можно, например, перейти к нужному тегу:

# Переключаемся в состояние репозитория на момент тега v1.2.0
git checkout v1.2.0

Типичные рабочие паттерны с git fetch

Ежедневное обновление перед началом работы

Многие команды рекомендуют начинать день с обновления локального репозитория:

# 1. Обновляем данные с сервера с удалением устаревших remote-tracking веток
git fetch -p

# 2. Смотрим изменения в основной ветке
git log main..origin/main --oneline

# 3. Обновляем локальную ветку main
git checkout main
git merge origin/main
# или
# git rebase origin/main

Так вы снижаете вероятность конфликтов и работаете с актуальной кодовой базой.

Проверка чужой ветки без ее локального создания

Иногда нужно посмотреть чужую ветку, не создавая сразу полноценную локальную ветку. Давайте посмотрим, как это сделать.

# Получаем все обновления из origin
git fetch origin

# Смотрим список remote-tracking веток
git branch -r

# Например нам нужна ветка origin/feature/login
git checkout origin/feature/login

Комментарии:

  • git checkout origin/feature/login переведет вас в "detached HEAD" состояние
  • вы можете просматривать файлы, запускать тесты, но не рекомендуется коммитить в таком состоянии
  • если ветка вам нужна для разработки, создайте от нее локальную:
# Создаем локальную ветку на основе удаленной
git checkout -b feature/login origin/feature/login

Обновление фичи-ветки относительно обновленного main

Распространенный сценарий: вы разрабатываете feature/login, а в main уже появились новые коммиты. Смотрите, как аккуратно подтянуть их.

# 1. Получаем свежие изменения
git fetch origin

# 2. Обновляем локальный main
git checkout main
git merge origin/main    # или git rebase origin/main

# 3. Возвращаемся в свою фичу
git checkout feature/login

# 4. Обновляем фичу относительно обновленного main
git rebase main
# или если команда предпочитает merge:
# git merge main

git fetch здесь играет роль надежного "транспортного слоя" — он доставляет вам свежую историю, а вы уже сами решаете, как ее интегрировать.

Настройка поведения git fetch через git config

fetch.prune

Как я уже показывал, очень удобно, когда устаревшие remote-tracking ветки удаляются автоматически. Чтобы включить это поведение для всех репозиториев:

# Включаем prune по умолчанию
git config --global fetch.prune true

Если нужно включить prune только для конкретного remote в одном репозитории:

# Включаем prune только для origin в текущем репозитории
git config remote.origin.prune true

fetch.recurseSubmodules

Если вы используете субмодули, то при fetch основного репозитория можно автоматически обновлять и субмодули. Для этого есть настройка:

# Включаем рекурсивный fetch для субмодулей
git config fetch.recurseSubmodules on-demand

Режимы:

  • on-demand — обновлять субмодули только когда это нужно
  • yes — всегда обновлять субмодули
  • no — не обновлять автоматически

Настройка по умолчанию для удаленного

Часто имя origin используется по умолчанию, но если вам нужно задать другой remote по умолчанию для fetch, вы можете перенастроить:

# Меняем remote по умолчанию для fetch в текущем репозитории
git remote set-url origin https://new-url.example.com/repo.git

Remote по умолчанию определяется при клонировании, но вы можете переименовать или перенастроить его по необходимости.

Диагностика и решение проблем с git fetch

Проблемы с аутентификацией

Если git fetch выдает ошибку авторизации (401, 403 или запрос пароля бесконечно), проверьте:

  1. Адрес удаленного репозитория:
git remote -v
  1. Правильность токена или SSH-ключа
  2. Настройки URL:
# Меняем протокол с HTTPS на SSH (или наоборот)
git remote set-url origin git@github.com:USER/REPO.git

Конфликт имен веток и тегов

Иногда на сервере может появиться тег с тем же именем, что и ветка. Тогда git fetch может ругаться на конфликт ссылок. В этом случае:

  1. Сначала посмотрите, что именно конфликтует
  2. Переименуйте локальный тег или ветку, или удалите его, если он вам не нужен:
# Удаляем локальный тег
git tag -d v1.0.0

# Удаляем локальную ветку
git branch -d old-branch

После этого повторите git fetch.

"Не подтягиваются" новые ветки

Если после git fetch вы не видите новую ветку, которую создали коллеги, проверьте:

# Список всех remote-tracking веток
git branch -r

Если ветка есть как origin/feature/x, но у вас нет локальной ветки, ее нужно создать:

# Создаем локальную ветку на основе удаленной
git checkout -b feature/x origin/feature/x

Если же даже в списке origin/* ветки нет, возможно, на сервере ее еще не запушили.

Заключение

Команда git fetch — это основа безопасной и предсказуемой работы с удаленными репозиториями. Она аккуратно разделяет два процесса: получение данных с сервера и интеграцию этих данных в вашу рабочую ветку. Благодаря этому вы можете:

  • держать локальный репозиторий в актуальном состоянии
  • заранее анализировать изменения перед слиянием
  • работать с несколькими удаленными репозиториями и форками
  • поддерживать список веток и тегов в порядке

Давайте зафиксируем ключевые моменты:

  • git fetch обновляет remote-tracking ветки (origin/, upstream/), но не трогает ваши локальные ветки и рабочие файлы
  • git pull = git fetch + git merge (или rebase) для текущей ветки
  • опция --prune помогает автоматически убирать устаревшие remote-tracking ветки
  • с помощью git fetch удобно работать с форками и несколькими remotes
  • теги можно скачивать выборочно (tag vX.Y.Z) или все сразу (--tags)
  • shallow fetch (--depth) позволяет экономить место и ускорять CI, если не нужна вся история

Когда вы начнете осознанно использовать git fetch в повседневной работе, у вас появится больше контроля над историей и меньше неожиданных конфликтов и "магических" изменений после pull.


Частозадаваемые технические вопросы по теме и ответы

Что делать, если после git fetch и git merge появились конфликты

  1. Git сообщит, в каких файлах конфликты.
  2. Откройте эти файлы в редакторе и найдите конфликтные блоки с маркерами вида <<<<<<<, =======, >>>>>>>.
  3. Аккуратно выберите нужный вариант или объедините оба фрагмента.
  4. Удалите маркеры конфликтов и сохраните файл.
  5. Пометьте файлы как решенные:
git add путь/к/файлу
  1. Завершите merge:
git commit

Как отменить результаты merge после git fetch если что-то пошло не так

  1. Найдите предыдущий коммит перед merge:
git log --oneline
  1. Если merge-коммит был последним и вы хотите просто откатить ветку:
git reset --hard HEAD~1
  1. Если merge уже был запушен, вместо reset лучше использовать revert:
git revert -m 1 <hash_merge-коммита>

Это создаст новый коммит, отменяющий изменения merge.

Как сделать так чтобы git pull всегда делал rebase а не merge

Если вам нравится история без лишних merge-коммитов, настройте pull:

# Для всех репозиториев
git config --global pull.rebase true

# Только для текущего репозитория
git config pull.rebase true

Теперь git pull будет эквивалентен:

git fetch
git rebase origin/ТЕКУЩАЯ_ВЕТКА

Почему после git fetch --all я вижу странные remote-tracking ветки

Часто это результат того, что у вас настроено несколько remotes с разными наборами веток. Проверьте:

git remote -v
git branch -r

Если какие-то remote вам больше не нужны, удалите их:

git remote remove имя_remote

Лишние remote-tracking ветки можно почистить через:

git fetch --all --prune

Как узнать какие именно объекты скачал последний git fetch

Git хранит информацию о последнем fetch в файле .git/FETCH_HEAD. Быстрый способ посмотреть, какие ветки обновлялись:

cat .git/FETCH_HEAD

Чтобы увидеть новые коммиты относительно вашей текущей ветки:

git log HEAD..FETCH_HEAD --oneline

Так вы увидите, какие коммиты появились после последнего fetch.

Стрелочка влевоПолучение и слияние в Git - команда git pullДобавление удаленного репозитория в Git с помощью git remote addСтрелочка вправо

Постройте личный план изучения Git до уровня Middle — бесплатно!

Git — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Git

Открыть базу знаний

Лучшие курсы по теме

изображение курса

Основы Git

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий