W3docs

git fetch

Команда git fetch: что делает, чем отличается от git pull, опции и примеры использования.

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

На этой странице рассматривается, что делает git fetch, как он обновляет ветки слежения за удалёнными репозиториями, наиболее полезные опции, как получить конкретную ветку или весь удалённый репозиторий, а также чем git fetch отличается от git pull.

Определение

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

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, --keepСохраняет скачанный pack-файл без его распаковки.
-p, --pruneУдаляет ссылки слежения за ветками, которых больше нет на удалённом сервере.
--depth=<depth>Ограничивает количество коммитов, загружаемых от вершины каждой ветки (неглубокое получение).
--dry-runПоказывает, что будет загружено, без фактической загрузки данных.

Чтобы удалить ссылки слежения для веток, которых больше нет на удалённом сервере, используйте --prune:

git fetch --prune

Чтобы получить данные из всех настроенных удалённых репозиториев одновременно, используйте --all:

git fetch --all

Как получить удалённую ветку с помощью 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 для test feature_branch:

git fetch

git fetch test_repo feature_branch
From hostname:test/test_repo
* [new branch]      feature_branch -> test_repo/feature_branch

Это скачивает содержимое test_repo/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 &lt;new-branch-name&gt;

Вывод показывает, что мы находимся в состоянии отсоединённого 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

Типичный сценарий совместной работы

Вот сценарий, который поможет лучше понять эту концепцию.

Предположим, есть небольшая команда разработчиков из двух человек — Алиса и Боб. Они работают над проектом, размещённым в удалённом Git-репозитории под названием origin. Алиса клонирует репозиторий на свою локальную машину и начинает работать в ветке main, а Боб работает в отдельной ветке feature-branch.

1- Алиса создаёт новый файл README.md и вносит в него изменения. Затем она фиксирует и отправляет изменения в ветку main репозитория origin:

$ git add README.md
$ git commit -m "Add README file"
$ git push origin main

2- Тем временем Боб внёс изменения в feature-branch и отправил их в репозиторий origin:

$ git add some_file.txt
$ git commit -m "Add new feature"
$ git push origin feature-branch

3- Алиса понимает, что ей нужно включить изменения Боба в свою работу, и получает изменения из репозитория origin:

$ git fetch origin

4- После получения данных Алиса видит, что в feature-branch появились новые изменения:

$ git branch -r
  origin/HEAD -> origin/main
  origin/main
  origin/feature-branch

5- Алиса может теперь слить изменения Боба в свою ветку main:

$ git merge origin/feature-branch

6- Алиса разрешает возможные конфликты слияния и отправляет свои изменения в репозиторий origin:

$ git push origin main

7- Теперь Боб может получить изменения, сделанные Алисой:

$ git fetch origin

8- Боб видит, что в ветке main появились новые изменения:

$ git branch -r
  origin/HEAD -> origin/main
  origin/main
  origin/feature-branch

9- Боб может слить изменения Алисы в свою ветку feature-branch:

$ git merge origin/main

10- Боб разрешает возможные конфликты слияния и отправляет свои изменения в репозиторий origin:

$ git push origin feature-branch

И так цикл продолжается: и Алиса, и Боб используют git fetch для отслеживания изменений друг друга и отправки собственных изменений в репозиторий origin. Благодаря git fetch они поддерживают локальный репозиторий актуальным относительно изменений коллег, что помогает избегать конфликтов и обеспечивает плавный процесс совместной работы.

Git fetch vs git pull

Обе команды — git fetch и git pull — используются для загрузки содержимого из удалённого репозитория. Команда git fetch не сливает изменения в ваши локальные ветки автоматически — она лишь обновляет ветки слежения. Загруженное содержимое не затрагивает ваш локальный рабочий каталог, что позволяет безопасно просматривать коммиты перед слиянием. Команда git pull скачивает новое содержимое и автоматически сливает его в вашу текущую ветку. Это может привести к конфликтам слияния, поэтому рекомендуется запускать git pull только тогда, когда рабочая копия чиста.

Коротко говоря, git pull примерно эквивалентен git fetch с последующим git merge:

git pull origin main
# is similar to:
git fetch origin
git merge origin/main

Когда использовать git fetch

Используйте git fetch, когда хотите:

  • Увидеть, что изменилось, прежде чем интегрировать изменения. Сначала получите данные, затем изучите их с помощью git log origin/main.. или git diff main origin/main, и выполняйте слияние только тогда, когда будете готовы.
  • Обновить ветки слежения, не затрагивая свою работу. Удобно в середине задачи, когда в рабочем каталоге есть незафиксированные изменения, которые может нарушить git pull.
  • Удалить устаревшие ветки. git fetch --prune удаляет ссылки слежения для веток, которые были удалены на удалённом сервере.
  • Просмотреть ветку коллеги. Получите её, переключитесь на неё для изучения кода и решите, нужно ли выполнять слияние.

Практика

Практика
Какие утверждения о команде git fetch верны?
Какие утверждения о команде git fetch верны?
Was this page helpful?