Команда fetch
позволяет получить информацию с удаленного репозитория,
например получить новые ветки, теги и уже после получить содержимое.
Почему нужен fetch
Если на удаленном репозитории появилась новая ветка, локально мы об этом не знаем. Для обновления информации о новых ветках, коммитах, тегах в локальном репозитории используется fetch.
Часто это происходит неявно, если используется IDE или git клиент. Но попробуйте локально
переключится на удаленную ветку - ничего не выйдет, пока не выполнится fetch
.
Примеры работы с fetch
В примере наглядно демонстрируется состояние удаленного и локального репозитория.
Начнем с клонирования репозитория
В нашем случае в удаленном репе одна ветка main. Локально еще не получили репозиторий.
remote local
|-main
Клонируем репозиторий и локально получаем главную ветку по-умолчанию:
remote local
|-main |-main
После этого, другой разработчик написал код в новой ветки:
remote local
|-main |-main
|-feat-1
Локально мы не знаем об этой ветки, это можно проверить выполнив команду
просмотра локальных веток git branch
и получить:
* main
Все верно, локально у нас одна ветка и мы находимся на ней, о чем
говорит *. Хотя в удаленном репозитории две ветки. Даже если мы посмотрим
список удаленных веток командой git branch -r
, получим:
origin/HEAD -> origin/main
origin/main
Мы снова получим только состояние репозиторий в момент клонирования,
ведь это локальные данные. И если мы попробуем переключиться на ветку feat-1 -
у нас ничего не выйдет git checkout feat-1
:
error: pathspec 'feat-1' did not match any file(s) known to git
Так давайте получим свежие данные из репозитория.
Команда git fetch
запросит с удаленного репозитория список изменений
и запишет в локальный репозиторий. Но при этом ни происходит попыток слияния,
только получение новых данных.
После выполнения команды git fetch
получим вывод:
From gitlab.com:sendel/fetch-ex
* [new branch] feat-1 -> origin/feat-1
Мы получили информацию о новое ветку в удаленном репозитории. Сейчас состояние репозиториев выглядит так:
remote local
|-main |-main
|-feat-1 |- 👻 feat-1
Информация есть о удаленной ветки есть, но не зря она как приведение. Локально этой ветки
еще не существует. Команда git branch -r
выведет новую ветку,
а список локальных git branch
так и останется содержать одну main.
При этом, мы можем переключится на ветку feat-1
, будет создана локальная ветка
и она будет указывать на feat-1
ветку удаленного репозитория. Выполним
команду перехода на ветку feat-1
git checkout feat-1
:
Branch 'feat-1' set up to track remote branch 'feat-1' from 'origin'.
Switched to a new branch 'feat-1'
Теперь локально создалась ветка feat-1
и связалась с удаленной веткой feat-1
.
remote local
|-main |-main
|-feat-1 |-feat-1
Проверить можем командой git branch -a
, таким образом получим список всех веток,
как локальных, так и удаленных:
* feat-1
main
remotes/origin/HEAD -> origin/main
remotes/origin/feat-1
remotes/origin/main
Получается, команда git fetch
неизбежно требуется для получения любых новых
сведений из удаленного репозитория.
А как же pull?
При выполнении команды git pull
, вызывается fetch
и далее уже полученные данные
сливаются с выбранной веткой.
Это можно легко проверить, если вызвать git pull -v
, параметр v (verbose) выводит
подробную информацию о ходе выполнения команды:
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 287 bytes | 95.00 KiB/s, done.
From gitlab.com:sendel/fetch-ex
e033308..4bbebd7 feat-2 -> origin/feat-2
= [up to date] feat-1 -> origin/feat-1
= [up to date] main -> origin/main
Updating e033308..4bbebd7
Fast-forward
feat-2 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Первой выполняется fetch, и далее уже слияние.
Вот такая она - призрачная команда, без которой не обойтись 👻