git fetch
Определение
Команда git fetch используется для загрузки коммитов, объектов и ссылок из удалённого репозитория в локальный репозиторий. Она используется, чтобы увидеть, над чем работали другие участники команды.

Как это работает с удалёнными ветками
Git хранит локальные и удалённые коммиты и разделяет их с помощью ссылок на ветки. Ссылки для локальных веток хранятся в /.git/refs/heads/. Чтобы увидеть список ссылок локальных веток, выполните команду git branch.
git branch
git branch
* master
crossword
solverЕсли просмотреть содержимое каталога /.git/refs/heads/, будет следующий вывод:
ls ./.git/refs/heads/
ls ./.git/refs/heads/
master
crossword
solverСсылки удалённых веток хранятся в каталоге ./.git/refs/remotes/. Чтобы увидеть удалённые ветки, используйте флаг -r с git branch. Вот вывод после получения данных из удалённого репозитория:
git branch -r
git branch -r
origin/master
origin/crossword
origin/solver
remote-repo/master
remote-repo/other-featureВывод показывает удалённые ветки с префиксом origin/. Вы можете просматривать удалённые ветки с помощью команд git checkout и git log. После одобрения изменений удалённой ветки вы можете слить её с локальной веткой с помощью команды git merge. Вместо этого используйте команду git pull, чтобы сократить процесс.
Общие параметры
| --all | Загружает все удалённые ветки. |
|---|---|
| -k or --keep | Сохраняет загруженный pack. |
| -p or --prune | Удаляет ссылки отслеживания удалённых веток, которых не было на удалённом репозитории до выполнения fetch. |
--depth=<depth> | Ограничивает количество коммитов, загружаемых с вершины истории каждой удалённой ветки. |
Чтобы удалить ссылки отслеживания для веток, которых больше не существует на удалённом репозитории, используйте --prune:
git fetch --pruneКак выполнить git fetch удалённой ветки
Здесь мы покажем шаги получения удалённой ветки и обновления локального рабочего состояния в соответствии с содержимым удалённого репозитория. В следующем примере у нас есть центральный репозиторий origin, из которого локальный репозиторий был клонирован с помощью команды git clone. Есть ещё один удалённый репозиторий с именем test_repo, содержащий feature_branch, который нужно настроить и получить.
Первый шаг — настроить удалённый репозиторий с помощью git remote:
git remote
git remote add test_repo git@hostname:test/test_repo.gitИспользуя URL репозитория коллеги, мы создали на него ссылку. Для загрузки содержимого выполните git fetch для тестовой feature_branch:
git fetch
git fetch test_repo feature_branch
From hostname:test/test_repo
* [new branch] feature_branch -> test_repo/feature_branchЭто интегрирует содержимое test/feature_branch в локальный репозиторий. Теперь используйте команду git checkout, чтобы переключиться на загруженную удалённую ветку:
git checkout test_repo/feature_branch
git checkout test_repo/feature_branch
Note: checking out 'test_repo/feature_branch'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can drop all the commits you make in this
state without influencing branches by executing another checkout.
If you want to generate a new branch for maintaining commits you create, you may
do so (now or later) if you use -b with the checkout command again. Example:
git checkout -b <new-branch-name>Вывод показывает, что мы находимся в состоянии detached HEAD, что означает, что ссылка HEAD указывает напрямую на коммит, а не на ветку.
С помощью команды git checkout можно создать новую локальную ветку из ссылки test/feature_branch:
git checkout -b local_feature_branch test_repo/feature_branch
git checkout -b local_feature_branch test_repo/feature_branchНовая локальная ветка создаётся, а HEAD обновляется так, чтобы указывать на последнее удалённое содержимое.
Синхронизация origin с помощью git fetch
Следующий пример показывает, как синхронизировать локальный репозиторий с веткой master центрального репозитория:
git fetch origin
git fetch originВ выводе будут показаны загруженные ветки:
git fetch origin output
b341bc3..32a45b1 master -> origin/master
b341bc3..7a52a22 develop -> origin/develop
* [new branch] some-feature -> origin/some-featureВызовите git log, используя origin/master в качестве фильтра, чтобы показать коммиты, добавленные в upstream master:
git log --oneline master..origin/master
git log --oneline master..origin/masterПроверьте изменения и слейте их с локальной веткой master:
git checkout master && git log origin/master
git checkout master
git log origin/masterВыполните git merge origin/master, чтобы синхронизироваться с изменениями upstream:
git merge
git merge origin/masterПример типичного сценария:
Вот сценарий, который поможет вам лучше понять эту концепцию:
Предположим, что есть небольшая команда разработки из двух разработчиков — Alice и Bob. Они работают над проектом, размещённым в удалённом Git-репозитории под названием origin. Alice клонирует репозиторий на свой локальный компьютер и начинает работать в ветке main, а Bob работает в отдельной ветке под названием feature-branch.
1- Alice создаёт новый файл с именем README.md и вносит в него некоторые изменения. Затем она фиксирует и отправляет свои изменения в ветку main репозитория origin:
$ git add README.md
$ git commit -m "Add README file"
$ git push origin main2- Тем временем Bob внёс некоторые изменения в feature-branch и отправил их в репозиторий origin:
$ git add some_file.txt
$ git commit -m "Add new feature"
$ git push origin feature-branch3- Alice понимает, что ей нужно включить изменения Bob в свою работу, поэтому она получает изменения из репозитория origin:
$ git fetch origin4- После получения изменений Alice видит, что в feature-branch появились новые изменения:
$ git branch -r
origin/HEAD -> origin/main
origin/main
origin/feature-branch5- Теперь Alice может слить изменения Bob в свою ветку main:
$ git merge origin/feature-branch6- Alice разрешает все конфликты слияния, а затем отправляет свои изменения в репозиторий origin:
$ git push origin main7- Теперь Bob может получить изменения, внесённые Alice:
$ git fetch origin8- Теперь Bob видит, что в ветке main появились новые изменения:
$ git branch -r
origin/HEAD -> origin/main
origin/main
origin/feature-branch9- Bob может слить изменения, внесённые Alice, в свою ветку feature-branch:
$ git merge origin/main10- Bob разрешает все конфликты слияния, а затем отправляет свои изменения в репозиторий origin:
$ git push origin feature-branchИ так цикл продолжается: и Alice, и Bob используют git fetch, чтобы отслеживать изменения друг друга и отправлять свои собственные изменения в репозиторий origin. Используя git fetch, они могут поддерживать свой локальный репозиторий в актуальном состоянии с изменениями, внесёнными их коллегами, что помогает избежать конфликтов и обеспечивает более плавный процесс совместной работы.
Git fetch vs git pull
И git fetch, и git pull используются для загрузки содержимого из удалённого репозитория. Команда git fetch не сливает изменения автоматически в ваши локальные ветки; она лишь обновляет ваши удалённые отслеживаемые ветки. Полученное содержимое не влияет на ваш локальный рабочий каталог, что позволяет безопасно просматривать коммиты перед их слиянием. Команда git pull загружает новое содержимое и автоматически сливает его с вашей текущей веткой. Это может привести к конфликтам слияния, поэтому рекомендуется запускать git pull только тогда, когда ваша рабочая копия чиста.
Practice
What are the correct statements about the `git fetch` command as described in the W3Docs Git Tutorial?