Примечание модератора: Учитывая, что на этот вопрос уже было опубликовано шестьдесят семь ответов (некоторые из них удалены), подумайте, вносите ли вы что-то новое перед публикацией другого один.
В чем разница между git pull
и git fetch
?
Проще говоря, git pull
выполняет git fetch
, за которым следует git merge
.
Вы можете сделать git fetch
в любое время, чтобы обновить свои удаленные отслеживающие ветви в refs / remotes / < remote > /
.
Эта операция никогда не меняет ни одного из ваших локальных филиалов в «refs / heads» и безопасна для выполнения без изменения вашей рабочей копии. Я даже слышал о людях, которые периодически запускают «git fetch» на работе в фоновом режиме (хотя я бы не советовал это делать).
«Git Pull» - это то, что вы должны сделать, чтобы обновить локальную ветку с ее удаленной версией, а также обновить другие ветви удаленного отслеживания.
Документация Git - Git Pull :
В режиме по умолчанию
git pull
является сокращением дляgit fetch
, за которым следуетgit merge FETCH_HEAD
.
Когда вы используете pull
, Git пытается автоматически сделать вашу работу за вас. Он чувствителен к контексту , поэтому Git объединит все извлеченные коммиты в ветку, в которой вы сейчас работаете. pull
автоматически объединяет коммиты, не позволяя сначала их просмотреть . Если вы не управляете своими филиалами, вы можете столкнуться с частыми конфликтами.
Когда вы fetch
, Git собирает любые коммиты из целевой ветки, которых нет в вашей текущей ветке, и сохраняет их в локальном репозитории . Однако он не объединяет их с вашей текущей веткой . Это особенно полезно, если вам нужно поддерживать ваш репозиторий в актуальном состоянии, но вы работаете над чем-то, что может сломаться, если вы обновите свои файлы.
Чтобы интегрировать коммиты в основную ветку, вы используете merge
.
Важно противопоставить философию дизайна git философии более традиционного инструмента управления источниками, такого как SVN
Subversion была разработана и построена с моделью клиент / сервер. Существует один репозиторий, который является сервером, и несколько клиентов могут извлечь код с сервера, работать над ним, а затем передать его обратно на сервер. Предполагается, что клиент всегда может связаться с сервером, когда ему необходимо выполнить операцию.
Git был разработан для поддержки более распределенной модели без необходимости в центральном хранилище (хотя вы, безусловно, можете использовать его, если хотите). Также git был разработан таким образом, чтобы клиенту и «серверу» не нужно было быть в сети одновременно. Git был разработан таким образом, чтобы люди по ненадежной ссылке могли обмениваться кодом даже по электронной почте. Можно работать полностью отключенным и записывать CD для обмена кодом через git.
Для поддержки этой модели git поддерживает локальный репозиторий с вашим кодом, а также дополнительный локальный репозиторий, который отражает состояние удаленного репозитория. Сохраняя копию удаленного хранилища локально, git может выяснить необходимые изменения, даже если удаленный репозиторий недоступен. Позже, когда вам нужно отправить изменения кому-то другому, git может перенести их как набор изменений из момента времени, известного в удаленное хранилище.
git fetch
- это команда, которая говорит: «Обновите мою локальную копию удаленного хранилища в актуальном состоянии.«
git pull
говорит "принесите изменения в удаленном хранилище туда, где я храню свой собственный код.«
Обычно git pull
делает это, делая git fetch
, чтобы обновить локальную копию удаленного репозитория, а затем объединяя изменения в свой собственный репозиторий кода и, возможно, в ваш рабочий копия.
Следует помнить, что на вашей рабочей станции часто есть как минимум три копии проекта. Одна копия - это ваш собственный репозиторий с вашей собственной историей коммитов. Второй экземпляр - это ваша рабочая копия, где вы редактируете и создаете. Третья копия - ваша локальная «кэшированная» копия удаленного хранилища.
Вот образ Оливера Стила о том, как все это сочетается:
введите описание изображения здесь!
Если есть достаточный интерес, я полагаю, что мог бы обновить изображение, чтобы добавить git clone
и git merge
...
Один из вариантов использования git fetch
заключается в том, что следующее сообщит вам о любых изменениях в удаленной ветке с момента вашего последнего извлечения... так что вы можете проверить перед тем, как выполнить фактическое извлечение, которое может изменить файлы в вашей текущей ветке и рабочей копии.
git fetch
git diff ...origin
См .: https://git-scm.com/docs/git-diff относительно синтаксиса двойного и тройного точек в команде diff
Мне стоило немного понять, в чем разница, но это простое объяснение. master
в вашем localhost является веткой.
Когда вы клонируете репозиторий, вы извлекаете весь репозиторий на локальный хост. Это означает, что в это время у вас есть указатель «начало / мастер» на «HEAD» и мастер, указывающий на тот же «HEAD».
когда вы начинаете работать и делаете коммиты, вы продвигаете главный указатель на HEAD
+ ваши коммиты. Но указатель «происхождение / мастер» все еще указывает на то, что было, когда вы клонировали.
Так что разница будет:
git fetch
, он просто извлечет все изменения в удаленном хранилище (GitHub) и переместит указатель origin / master в HEAD
. Тем временем ваш местный начальник филиала будет продолжать указывать, где он находится.git pull
, он в основном извлечет (как объяснено ранее) и объединит любые новые изменения в вашей основной ветке и переместит указатель на HEAD
.Кратко
git fetch
похож на pull
, но не сливается. то есть. он выбирает удаленные обновления (refs
и objects
), но ваш локальный остается прежним (т.е. origin / master
обновляется, но master
остается прежним) .
git pull
останавливается с пульта дистанционного управления и мгновенно сливается.
Больше
git clone
клонирует репо.
git rebase
сохраняет материал из вашей текущей ветки, который не находится в восходящей ветке, во временную область. Ваша ветка теперь такая же, как и до того, как вы начали свои изменения. Таким образом, git pull -rebase
будет снимать удаленные изменения, перематывать локальную ветку, воспроизводить ваши изменения поверх текущей ветки один за другим, пока вы не будете в курсе.
Кроме того, git branch -a
покажет вам, что именно происходит со всеми вашими филиалами - локальными и удаленными.
Этот пост в блоге был полезен:
Разница между git pull, git fetch и git clone (и git rebase) - Майк Пирс
и охватывает git pull
, git fetch
, git clone
и git rebase
.
====
ОБНОВЛЕНИЕ
Я подумал, что обновим это, чтобы показать, как ты на самом деле будешь использовать это на практике.
Обновите локальное репо с пульта (но не объединяйтесь):
Git Fetch
После загрузки обновлений давайте посмотрим на различия:
git diff master origin / master
Если вы довольны этими обновлениями, объедините:
мерзавец тянет
Примечания:
На шаге 2: Подробнее о различиях между локальными и удаленными устройствами см .: https://stackoverflow.com/questions/1800783/compare-local-git-branch-with-remote-branch
На шаге 3: это, вероятно, более точно (например,. на быстро меняющемся репо), чтобы сделать `git rebase origin здесь. См. @Justin Ом комментарий в другом ответе.
Смотрите также: http://longair.net/blog/2009/04/16/git-fetch-and-merge/
& Лт; pre > git-pull - извлечение и слияние с другим хранилищем или локальной веткой СИНОПИС
git pull < options > < репозиторий > < refspec > ... ОПИСАНИЕ
Запускает git-fetch с заданными параметрами и вызывает git-merge для слияния извлеченные головы в текущую ветку. С --rebase, вызывает git-rebase вместо мерге.
Обратите внимание, что вы можете использовать . (текущий каталог) как & lt; репозиторий > тянуть из локального репозитория - это полезно при объединении локальных ветвей в текущую ветку.
Также обратите внимание, что опции предназначены для самого git-pull и базового git-merge должны быть указаны перед опциями, предназначенными для git-fetch. & Лт; / pre >
Вы бы потянули, если хотите, чтобы истории слились, вы бы получили, если бы просто «хотели код», так как какой-то человек помечал некоторые статьи здесь.
Вы можете извлечь из удаленного репозитория, увидеть различия, а затем извлечь или объединить.
Это пример для удаленного репозитория с именем origin
и ветки с именем master
, отслеживающей удаленную ветку origin / master
:
git checkout master
git fetch
git diff origin/master
git rebase origin master
Короткий и простой ответ заключается в том, что «git pull» - это просто «git fetch», за которым следует «git merge».
Очень важно отметить, что git pull
будет автоматически сливаться, нравится вам это или нет . Это может, конечно, привести к конфликтам слияния. Допустим, ваш пульт "origin", а ваша ветка "master". Если вы «подобрали происхождение / мастер» перед извлечением, у вас должно быть некоторое представление о потенциальных конфликтах слияния, и вы можете соответствующим образом подготовить локальную ветвь.
В дополнение к растяжению и толчку, некоторые рабочие процессы включают «гит-ребазу», такую как эта, которую я перефразирую из связанной статьи:
git pull origin master
git checkout foo-branch
git rebase master
git push origin foo-branch
Если вы окажетесь в такой ситуации, у вас может возникнуть соблазн «вытащить - перебазировать». Если вы действительно, действительно не знаете, что делаете, я бы посоветовал против этого. Это предупреждение на странице man
для git-pull
, версия 2.3.5
:
Это потенциально опасный режим работы. Это переписывает история, которая не сулит ничего хорошего, когда вы опубликовали эту историю уже. Не используйте эту опцию, если вы не прочитали git-rebase (1) тщательно.
Хорошо , вот некоторая информация о git pull
и git fetch
, чтобы вы могли понять реальные различия... в нескольких простых словах fetch получает последние данные, но не изменяет код и не собирается связываться с вашим текущим кодом локальной ветки, но pull получает изменения кода и объединяет его с вашей локальной веткой, читайте дальше, чтобы получить более подробную информацию о каждом:
Он загрузит все refs и объекты и любые новые ветки в ваш локальный репозиторий...
Получить ветки и / или теги (совместно, «отражает») из одного или нескольких другие репозитории, а также объекты, необходимые для их заполнения истории. Обновлены ветки удаленного отслеживания (см. Описание
< refspec > ниже для способов контролировать это поведение).По умолчанию любой тег, который указывает на извлекаемые истории, является также извлекается; эффект состоит в том, чтобы извлечь теги, которые указывают на ветви, которые Вы заинтересованы в. Это поведение по умолчанию можно изменить с помощью параметры --tags или --no-tags или путем настройки удаленный.< name > .tagOpt. Используя refspec, который явно выбирает теги Вы можете получить теги, которые не указывают на интересующие вас ветви в том же духе.
git fetch может быть извлечен из одного именованного хранилища или URL, или из нескольких репозиториев одновременно, если < group > дано и есть пульты.& Лт; группа > запись в файле конфигурации. (См. Git-config 1).
Если пульт не указан, по умолчанию будет пульт дистанционного управления используется, если только нет ветки вверх по течению, настроенной для текущего ветка.
Имена ссылок, которые выбираются вместе с именами объектов они указывают на, написаны на .git / FETCH_HEAD. Эта информация может быть используется скриптами или другими командами git, такими как git-pull.
& Лт; hr >
< h2 > git pull < / h2 >Он будет применять изменения от Remote к текущей ветке в локальной сети...
Включает изменения из удаленного хранилища в текущую ветку. В режиме по умолчанию git pull является сокращением для git fetch, за которым следует git Git Merge FETCH_HEAD .
Точнее, git pull запускает git fetch с заданными параметрами и вызывает git merge, чтобы объединить извлеченные головки ветвей в ток ветка. С --rebase он запускает git rebase вместо git merge.
< репозиторий > должно быть имя удаленного репозитория, как передано git-fetch 1. < refspec > может назвать произвольный удаленный ref (например, имя тега) или даже коллекция ссылок с соответствующими ветки удаленного отслеживания (например,., refs / heads / : refs / remotes / origin / ), но обычно это имя ветки в удаленном хранилище.
Значения по умолчанию для < репозитория > и < branch > читаются с «удаленная» и «слиятельная» конфигурация для текущей ветки в установленном порядке git-branch --track.
& Лт; hr >
Я также создаю visual ниже, чтобы показать вам, как git fetch
и git pull
работают вместе...
введите описание изображения здесь! Это интерактивное графическое представление очень полезно в подстигнутом git: http://ndpsoftware.com/git-cheatsheet.html
git fetch
просто «загружает» изменения с удаленного на локальный репозиторий. git pull
загружает изменения и объединяет их в вашу текущую ветку. «В режиме по умолчанию« git pull »сокращается для« git fetch », за которым следует« git merge FETCH_HEAD ».«
Говоря о тяге и извлеките из приведенных выше ответов, я хотел бы поделиться интересным трюком
git pull --rebase
Эта приведенная выше команда - самая полезная команда в моей жизни git, которая сэкономила много времени.
Прежде чем отправлять новые коммиты на сервер, попробуйте эту команду, и она автоматически синхронизирует последние изменения сервера (с помощью fetch + merge) и разместит ваш коммит вверху в git log. Не нужно беспокоиться о ручном натяжении / слиянии.
Найти подробности по адресу: http://gitolite.com/git-pull--rebase
Мне нравится иметь некоторое визуальное представление ситуации, чтобы понять эти вещи. Может быть, другие разработчики тоже хотели бы это увидеть, так что вот мое дополнение. Я не совсем уверен, что все это правильно, поэтому, пожалуйста, прокомментируйте, если вы найдете какие-либо ошибки.
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.
Некоторые основные преимущества наличия зеркала пульта дистанционного управления:
Я тоже боролся с этим. На самом деле я попал сюда с поиском в 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+ -
--------------------- ----------------------- -----------------------
Это помогло мне понять, почему выборка довольно важна.
Разница между GIT Fetch и GIT Pull может быть объяснена следующим сценарием:
Давайте рассмотрим пример того, что вы работаете над проектом с членами вашей команды. Таким образом, они будут одним из основных отделов проекта, и все участники должны раскошелиться на его собственный локальный репозиторий, а затем работать над этим локальным филиалом, чтобы модифицировать / добавлять модули, а затем возвращаться к основной ветке.
Так
Начальное состояние двух филиалов, когда вы разветвляли основной проект в локальном хранилище, будет таким: (A
, B
и C
- это уже завершенные модули проекта)
Теперь вы начали работать над новым модулем (представьте D
), и когда вы закончите модуль D
, вы захотите перенести его в основную ветку, но между тем происходит то, что один из ваших товарищей по команде разработал новый модуль E
, F
и модифицированный C
.& Лт; br >
Итак, теперь произошло то, что вашему локальному хранилищу не хватает первоначального прогресса проекта, и, таким образом, перенос ваших изменений в основную ветку может привести к конфликту и может привести к сбою вашего модуля D
.
Чтобы избежать таких проблем и работать параллельно с первоначальным прогрессом проекта, это два пути:
1. Git Fetch- Это загрузит все изменения, которые были внесены в проект origin / main branch, которых нет в вашей локальной ветке. И будет ждать, пока команда Git Merge применит изменения, которые были получены в вашем репозитории или ветке.
Так что теперь вы можете внимательно отслеживать файлы, прежде чем объединять их в свой репозиторий. И вы также можете изменить D
при необходимости из-за измененного C
.
2. Git Pull- Это обновит вашу локальную ветку веткой origin / main, т.е. на самом деле то, что он делает, это комбинация Git Fetch и Git сливаются один за другим.
Мы просто говорим:
git pull == git fetch + git merge
Если вы запустите git pull
, вам не нужно объединять данные в локальные. Если вы запускаете git fetch
, это означает, что вы должны запустить git merge
для получения последнего кода на локальном компьютере. В противном случае локальный машинный код не будет изменен без слияния.
Таким образом, в Git Gui, когда вы делаете выборку, вы должны объединить данные. Fetch сам не будет вносить изменения в код в вашем местном. Вы можете проверить это при обновлении кода, извлекая один раз получить и увидеть; код это не изменит. Тогда вы сливаетесь... Вы увидите измененный код.
git fetch
вытягивает код с удаленного сервера в ваши ветки отслеживания в вашем локальном хранилище. Если ваш пульт дистанционного управления называется origin
(по умолчанию), то эти ветви будут находиться в пределах origin /
, например origin / master
, origin / mybranch-123
и т. Д. Это не ваши текущие ветви, это локальные копии этих ветвей с сервера.
git pull
выполняет git fetch
, но затем также объединяет код из ветви отслеживания в вашу текущую локальную версию этой ветки. Если вы еще не готовы к этим изменениям, просто сначала «получите».
git fetch
будет извлекать удаленные ветви, чтобы вы могли git diff
или git объединить
их с текущей веткой. git pull
запустит fetch на удаленном брахе, отслеживаемом текущей веткой, а затем объединит результат. Вы можете использовать git fetch
, чтобы увидеть, есть ли какие-либо обновления в удаленной ветке без необходимости объединять их с вашей локальной веткой.