Команда git pull используется для извлечения и загрузки содержимого из удаленного репозитория и немедленного обновления локального репозитория этим содержимым. Слияние удаленных вышестоящих изменений в локальный репозиторий — это обычная задача рабочего процесса, возникающая при совместной работе на основе системы Git. Команда git pull на самом деле представляет собой комбинацию двух других команд: git fetch и git merge. На первом этапе git pull выполняется команда git fetch, ограниченная локальной веткой, на которую указывает указатель HEAD. Сразу после загрузки содержимого команда git pull выполняет слияние. Для слитого содержимого создается новый коммит, а указатель HEAD обновляется и начинает указывать на этот новый коммит.

Использование git pull

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

Сначала команда git pull запускает команду git fetch для загрузки содержимого из указанного удаленного репозитория. Затем выполняется команда git merge, позволяющая слить ссылки и указатели удаленного содержимого в новый локальный коммит. Чтобы лучше продемонстрировать процесс извлечения и слияния, рассмотрим пример. Предположим, у нас есть репозиторий с главной веткой master и удаленной веткой remote origin.

В этом сценарии команда git pull загрузит все изменения, начиная с того места, где разошлись локальная и главная ветки. В данном примере это точка E. Команда git pull получит удаленные коммиты из отходящей ветки (т. е. точки A‑B‑C). Затем процесс команды pull создаст новый локальный коммит слияния, включающий содержимое новых удаленных коммитов из отходящей ветки.

На вышеприведенной диаграмме мы видим новый коммит H. Это коммит слияния, в который входит содержимое удаленных коммитов A‑B‑C и который имеет общее сообщение в журнале. Этот пример демонстрирует одну из немногих стратегий слияния с помощью команды git pull. Чтобы сделать перебазирование, а не коммит слитого содержимого, укажите для команды git pull опцию --rebase. В следующем примере демонстрируется, как работает перебазирование с помощью команды pull. Предположим, что мы находимся в начальной точке нашей первой диаграммы и выполнили команду git pull --rebase.

На этой диаграмме видно, что при перебазировании с помощью команды pull не был создан новый коммит H. Вместо этого удаленные коммиты A‑B‑C были скопированы и добавлены в историю в виде коммита в локальной ветке origin/master.

Распространенные опции

git pull <remote>

Извлечь копию указанного удаленного содержимого текущей ветки и немедленно слить ее с локальной копией. Эта команда аналогична команде git fetch <удаленная>, после которой следует команда git merge origin/<текущая-ветка>.

git pull --no-commit <remote>

Подобно вызову по умолчанию, извлекает удаленное содержимое, но не создает новый коммит со слитым содержимым.

git pull --rebase <remote>

Аналогично предыдущей команде pull, только вместо команды git merge для интеграции удаленной ветки с локальной веткой используется команда git rebase.

git pull --verbose

Во время выполнения команды pull выдает подробный вывод о загружаемом содержимом и информацию о слиянии.

Обсуждение git pull

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

Сначала вы думаете, что ваш репозиторий синхронизирован, однако команда git fetch показывает, что с момента последней проверки версия origin ветки master была изменена. Затем команда git merge сразу интегрирует удаленную ветку master в локальную ветку.

Git pull и синхронизация

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

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

Сравнение pull и rebase

Опцию --rebase можно использовать, чтобы сохранить линейную историю и избежать ненужных коммитов слияния. Многие разработчики предпочитают выполнять перебазирование, а не слияние, как бы заявляя: «Я хочу, чтобы мои изменения добавились поверх всех остальных». В этом плане команда git pull с флагом --rebase больше похожа на команду svn update, чем на простую команду git pull.

На самом деле команда pull с опцией --rebase используется в рабочем процессе настолько часто, что для нее существует выделенная опция конфигурации:

git config --global branch.autosetuprebase always

После выполнения этой команды все команды git pull будут интегрироваться с помощью команды git rebase, а не git merge.

Примеры использования git pull

В нижеприведенных примерах показано, как использовать команду git pull в общих сценариях.

Поведение по умолчанию

git pull

Вызов команды git pull по умолчанию эквивалентен выполнению команд git fetch origin HEAD и git merge HEAD, где HEAD — это указатель на текущую ветку.

Команда git pull на удаленных ветках

git checkout new_feature
git pull <remote repo>

В этом примере сначала создается ветка <newfeature> и происходит переключение на нее. После этого выполняется команда git pull, в которой передается удаленный репозиторий <remote repo>. Это приводит к неявной загрузке (выполнению команды pull) ветки newfeature из удаленного репозитория <remote repo>. Как только загрузка завершается, начинается выполнение команды git merge.

Перебазирование с помощью git pull вместо слияния

В примерах ниже показано, как выполнить синхронизацию главной ветки master центрального репозитория с помощью перебазирования.

git checkout master
git pull --rebase origin

В этом примере ваши локальные изменения просто помещаются поверх изменений всех остальных участников разработки.