В чем разница между «git pull» и «git fetch»? - PullRequest
11016 голосов
/ 15 ноября 2008

Примечание модератора: Учитывая, что на этот вопрос уже отправлено шестьдесят семь ответов (некоторые из них удалены), подумайте, действительно ли вы добавив что-нибудь новое перед публикацией другого.

В чем различия между git pull и git fetch?

Ответы [ 40 ]

145 голосов
/ 16 мая 2011

Короткий и простой ответ таков: git pull - это просто git fetch, за которым следует git merge.

Очень важно отметить, что git pull автоматически объединится, нравится вам это или нет . Это может, конечно, привести к конфликтам слияния. Допустим, ваш пульт дистанционного управления origin, а ваша ветвь - master. Если вы git diff origin/master перед извлечением, у вас должно быть некоторое представление о потенциальных конфликтах слияний и вы могли бы соответствующим образом подготовить свое местное отделение.

В дополнение к вытягиванию и подталкиванию некоторые рабочие процессы включают git rebase, такой как этот, который я перефразирую из связанной статьи:

git pull origin master
git checkout foo-branch
git rebase master
git push origin foo-branch

Если вы окажетесь в такой ситуации, у вас может возникнуть искушение git pull --rebase. Если вы действительно, действительно не знаете, что делаете, я бы посоветовал против этого. Это предупреждение со страницы man для git-pull, версия 2.3.5:

Это потенциально опасный режим работы. Переписывает история, которая не сулит ничего хорошего, когда вы опубликовали эту историю уже. Не используйте эту опцию, если вы не читали git-rebase (1) тщательно.

129 голосов
/ 21 июня 2017

OK , вот некоторая информация о git pull и git fetch, так что вы можете понять реальные различия ... в нескольких простых словах fetch получает последние данные , но не изменения кода и не буду связываться с вашим текущим кодом локальной ветки, но потяните получите изменения кода и объедините их с вашей локальной веткой, читайте дальше, чтобы получить более подробную информацию о каждом:

git fetch

Он загрузит все ссылки и объекты и любые новые ветви в ваш локальный репозиторий ...

Извлечение ветвей и / или тегов (вместе "refs") из одного или нескольких другие хранилища, а также объекты, необходимые для завершения их истории. Обновлены ветки удаленного слежения (см. Описание ниже для способов контролировать это поведение).

По умолчанию любой тег, который указывает на историю выборки, также извлечен; Эффект заключается в получении тегов, которые указывают на ветви, которые Вы заинтересованы. Это поведение по умолчанию может быть изменено с помощью параметры --tags или --no-tags или путем настройки remote..tagOpt. Используя refspec, который явно выбирает теги, Вы можете выбрать теги, которые не указывают на интересующие вас ветки в том числе.

git fetch может извлекать данные либо из одного именованного репозитория, либо по URL, либо из нескольких репозиториев одновременно, если дано и есть пульты дистанционного управления. запись в файле конфигурации. (См. Git-config 1 ).

Если пульт не указан, по умолчанию исходный пульт будет используется, если нет восходящей ветви, настроенной для текущего филиал.

Имена ссылок, которые выбираются вместе с именами объектов. они указывают на, записаны в .git / FETCH_HEAD. Эта информация может быть используется скриптами или другими командами git, такими как git-pull.


git pull

Будет применено изменение от remote к текущей ветви в локальном ...

Включает изменения из удаленного репозитория в текущую ветку. В режиме по умолчанию git pull - это сокращение от git fetch, за которым следует git merge FETCH_HEAD.

Точнее, git pull запускает git fetch с заданными параметрами и вызывает git merge, чтобы объединить полученные заголовки веток с текущим ветка. С --rebase он запускает git rebase вместо git merge.

должно быть именем удаленного репозитория, переданным в ГИТ-выборки 1 . можно назвать произвольную удаленную ссылку (например, имя тега) или даже сборник ссылок с соответствующими ветви удаленного отслеживания (например, refs / heads / : refs / remotes / origin / ), но обычно это имя ветки в удаленном хранилище.

Значения по умолчанию для и считываются из «Удаленная» и «объединить» конфигурации для текущей ветви, как установлено git-branch --track.


Я также создаю визуал ниже, чтобы показать вам, как git fetch и git pull работают вместе ...

git pull and git fetch

123 голосов
/ 06 февраля 2015

enter image description here

Это интерактивное графическое представление очень полезно в понимании git: http://ndpsoftware.com/git-cheatsheet.html

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

119 голосов
/ 23 декабря 2015

Бонус:

Говоря о pull & fetch в приведенных выше ответах, я хотел бы поделиться интересным трюком:

git pull --rebase

Эта команда является самой полезной в моей жизни в git, которая сэкономила много времени.

Прежде чем отправлять ваши новые коммиты на сервер, попробуйте эту команду, и она автоматически синхронизирует последние изменения сервера (с извлечением + слиянием) и поместит ваш коммит наверху в git log. Не нужно беспокоиться о ручном вытягивании / слиянии.

Найти подробности можно по адресу: http://gitolite.com/git-pull--rebase

111 голосов
/ 20 февраля 2014

Мне нравится иметь некоторое визуальное представление ситуации, чтобы понять эти вещи. Может быть, другие разработчики тоже захотят это увидеть, так что вот мое дополнение. Я не совсем уверен, что все правильно, поэтому, пожалуйста, прокомментируйте, если обнаружите какие-либо ошибки.

                                         LOCAL SYSTEM
                  . =====================================================    
================= . =================  ===================  =============
REMOTE REPOSITORY . REMOTE REPOSITORY  LOCAL REPOSITORY     WORKING COPY
(ORIGIN)          . (CACHED)           
for example,      . mirror of the      
a github repo.    . remote repo
Can also be       .
multiple repo's   .
                  .
                  .
FETCH  *------------------>*
Your local cache of the remote is updated with the origin (or multiple
external sources, that is git's distributed nature)
                  .
PULL   *-------------------------------------------------------->*
changes are merged directly into your local copy. when conflicts occur, 
you are asked for decisions.
                  .
COMMIT            .                             *<---------------*
When coming from, for example, subversion, you might think that a commit
will update the origin. In git, a commit is only done to your local repo.
                  .
PUSH   *<---------------------------------------*
Synchronizes your changes back into the origin.

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

  • Производительность (прокручивать все коммиты и сообщения, не пытаясь протолкнуть его через сеть)
  • Обратная связь о состоянии вашего локального репо (например, я использую SourceTree Atlassian, который даст мне лампочку, указывающую, если я совершаю коммит вперед или позади по сравнению с источником. обновляется GIT FETCH).
102 голосов
/ 17 июля 2012

Я тоже с этим боролся. На самом деле я попал сюда с поиском в Google точно такого же вопроса. Чтение всех этих ответов, наконец, нарисовало картину в моей голове, и я решил попытаться разобраться в этом, глядя на состояние 2 репозиториев и 1 песочницы и действий, выполненных во времени при просмотре их версии. Итак, вот что я придумала. Пожалуйста, поправьте меня, если я что-то напутал.

Три репо с выборкой:

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - fetch               -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     -                     -
- @ R01             -     - @ R01+              -     - @R01+               -
---------------------     -----------------------     -----------------------

Три репо с вытягиванием

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - pull                -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     - merged with R02     -
- @ R01             -     - @ R01+              -     - @R02+               -
---------------------     -----------------------     -----------------------

Это помогло мне понять, почему выборка очень важна.

90 голосов
/ 07 февраля 2017

Разницу между GIT Fetch и GIT Pull можно объяснить следующим сценарием: (Помните, что картинки говорят громче слов! Я предоставил графическое представление)

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

Итак, Начальное состояние двух ветвей, когда вы разветвляли основной проект в вашем локальном хранилище, будет таким - (A, B и C - модули, уже завершенные для проекта)

enter image description here

Теперь вы начали работать над новым модулем (предположим, D), и когда вы завершили модуль D, вы хотите перенести его в основную ветку, но между тем происходит то, что один из ваших товарищей по команде имеет разработан новый модуль E, F и изменен C.
Итак, теперь произошло то, что в вашем локальном репозитории не хватает первоначального прогресса проекта, и поэтому внесение ваших изменений в основную ветку может привести к конфликту и может привести к неисправности вашего модуля D.

enter image description here

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

1. Git Fetch- Это загрузит все изменения, которые были внесены в проект origin / main ветки, которых нет в вашей локальной ветке. И будет ждать, пока команда Git Merge применит изменения, которые были извлечены для вашего хранилища или филиала.

enter image description here

Итак, теперь вы можете внимательно следить за файлами, прежде чем объединять их с вашим хранилищем. И вы также можете изменить D при необходимости из-за Modified C.

enter image description here

2. Git Pull- Это обновит вашу локальную ветку с источником / главной веткой, то есть фактически то, что она делает, это комбинация Git Fetch и Git слияния друг за другом. Но это может привести к возникновению конфликтов, поэтому рекомендуется использовать Git Pull с чистой копией.

enter image description here

82 голосов
/ 21 февраля 2013

Мы просто говорим:

git pull == git fetch + git merge

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

Так что в Git Gui, когда вы делаете выборку, вы должны объединить данные. Сама Fetch не будет вносить изменения в ваш локальный код. Вы можете проверить это при обновлении кода, выбрав один раз принеси и посмотри; код не изменится. Затем вы сливаетесь ... Вы увидите измененный код.

79 голосов
/ 20 сентября 2013

git fetch загружает код с удаленного сервера в ваши ветви отслеживания в вашем локальном хранилище. Если ваш пульт имеет имя origin (по умолчанию), тогда эти ветви будут в пределах origin/, например origin/master, origin/mybranch-123 и т. Д. Это не ваши текущие ветви, они локальные копии этих веток с сервера.

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

75 голосов
/ 27 ноября 2012

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

...