В чем разница между «git pull» и «git fetch»?


11921

Каковы различия между git pullи git fetch?


364
Я нашел эту хорошо написанную статью о git fetch и git pull, которую стоит прочитать: longair.net/blog/2009/04/16/git-fetch-and-merge
Маркос Оливейра

51
Наш альтернативный подход стал git fetch; git reset --hard origin/masterчастью нашего рабочего процесса. Он сносит локальные изменения, держит вас в курсе событий, но мастер гарантирует, что вы не просто добавите новые изменения поверх текущих изменений и создадите беспорядок. Мы использовали его некоторое время, и на практике это выглядит намного безопаснее. Просто убедитесь, что вы добавили / зафиксировали / спрятали любую незавершенную работу в первую очередь!
Майкл Даррант

26
Убедитесь, что вы знаете, как правильно использовать git stash. Если вы спрашиваете о «вытягивании» и «извлечении», то, возможно, «сундук» также нужно будет объяснить ...
Генри Хелайн,

36
Многие из Mercurial продолжают использовать «git pull», думая, что это эквивалентно «hg pull». Что это не так. Git эквивалентно «hg pull» - это «git fetch».
Серж Шульц

8
Команда git fetch извлекает обновленный код с веткой, а также получает новые добавленные ветки в вашей локальной сети, команда git pull извлекает только обновленный код только текущей ветки
Kartik Patel

Ответы:


9920

Проще говоря, 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.


326
«« Git pull »- это то, что вы должны сделать, чтобы обновить хранилище» <- обновление хранилища уже не было выполнено fetch? Разве вы не имеете в виду, что это приводит ваши местные филиалы в соответствие с удаленными филиалами? Чтобы объединить: он объединяет удаленные ветви с вашими локальными копиями этих веток, или что именно здесь объединяется?
Альберт

194
@ Альберт: Да, это странно сформулировано. git pullвсегда будет сливаться с текущей веткой . Таким образом , вы выбираете какую ветвь вы хотите , чтобы вытащить из , и она тянет его в текущую ветку. Из ветви могут быть локальными или удаленными; это может быть даже удаленная ветка, которая не зарегистрирована git remote(то есть вы передаете URL-адрес в git pullкомандной строке).
интуитивно

129
@espertus: Нет. Нажатие никогда не приводит к автоматическому слиянию. Ожидается, что пользователь выполнит извлечение, локально разрешив конфликты слияния, а затем вернется к удаленному.
Грег Хьюгилл

33
Если я нахожусь /home/alice/и делаю git fetch /home/bob, какие параметры я должен передать последующим git merge?
ripper234

106
Примечание для людей, изучающих Git: на pullсамом деле нельзя подражать fetchплюсу a merge. Я только что получил изменение, при котором изменяется только указатель удаленной ветви, и mergeотказывается что-либо делать. pullс другой стороны, быстро переходит к моей ветви отслеживания.
Роман Старков

2173
  • Когда вы используете pull, Git пытается автоматически выполнить вашу работу за вас. Он чувствителен к контексту , поэтому Git объединит любые извлеченные коммиты с веткой, в которой вы сейчас работаете. pull Автоматически объединяет коммиты, не давая вам предварительно просмотреть их . Если вы не управляете своими филиалами, вы можете столкнуться с частыми конфликтами.

  • Когда вы fetch, Git собирает любые коммиты из целевой ветки, которых нет в вашей текущей ветке, и сохраняет их в вашем локальном репозитории . Однако он не объединяет их с вашей текущей веткой . Это особенно полезно, если вам нужно регулярно обновлять хранилище, но вы работаете над тем, что может сломаться, если вы обновите свои файлы. Чтобы интегрировать коммиты в вашу основную ветку, вы используете merge.


34
Согласен, отличный комментарий. Вот почему я ненавижу мерзавца. Когда было бы когда-нибудь целесообразно, чтобы инструмент редактирования вносил изменения для вас? И разве это не то, что делает слияние двух файлов? Что если эти две правки физически разделены в файле, но ЛОГИЧЕСКИ не совпадают?
Ли Диксон

126
Короткая позиция @elexhobby, git fetchобновляет только ваш .git/каталог (AKA: локальный репозиторий) и ничего снаружи .git/(AKA: рабочее дерево). Это не меняет ваши местные филиалы, и это не касается masterтакже. remotes/origin/masterХотя это касается (см. git branch -avv). Если у вас есть больше пультов, попробуйте git remote update. Это git fetchдля всех пультов в одной команде.
Тино

24
@ Тино твой действительно самый важный момент. Люди могут не знать, что «удаленные» ветки на самом деле хранятся в виде набора хешей .git/refs/remotes/origin/.
Крис

13
Когда вы выбираете, Git собирает любые коммиты из целевой ветки, которых нет в вашей текущей ветке, и сохраняет их в вашем локальном репозитории - как я могу увидеть, что было получено с удаленного компьютера, и как мне объединить его с моими локальными ветками?
ス レ ッ ク ス

13
@ Тино То, что я до сих пор не понимаю ... это какой смысл? Зачем использовать fetch, если он только обновляет .git? Какова предполагаемая выгода и что я должен делать после этого?
BadHorsie

1210

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

Subversion был спроектирован и построен с использованием модели клиент / сервер. Существует один репозиторий, который является сервером, и несколько клиентов могут получить код с сервера, поработать с ним, а затем передать его обратно на сервер. Предполагается, что клиент всегда может связаться с сервером, когда ему нужно выполнить операцию.

Git был разработан для поддержки более распределенной модели без необходимости в центральном хранилище (хотя вы, безусловно, можете использовать ее, если хотите). Кроме того, git был спроектирован так, что клиент и «сервер» не должны быть в сети одновременно. Git был разработан для того, чтобы люди по ненадежной ссылке могли обмениваться кодом даже по электронной почте. Можно работать полностью отключенным и записывать CD для обмена кодом через git.

Для поддержки этой модели git поддерживает локальный репозиторий с вашим кодом, а также дополнительный локальный репозиторий, который отражает состояние удаленного репозитория. Сохраняя копию удаленного репозитория локально, git может выяснить, какие изменения необходимы, даже если удаленный репозиторий недоступен. Позже, когда вам нужно будет отправить изменения кому-то еще, git может передать их как набор изменений с момента времени, известного удаленному хранилищу.

  • git fetch это команда, которая говорит «привести мою локальную копию удаленного хранилища в актуальное состояние».

  • git pull говорит «перенесите изменения в удаленный репозиторий туда, где я храню свой собственный код».

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

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


75
Технически, локальные и удаленные репозитории действительно одно и то же. В Git хранилище - это DAG коммитов, указывающих на их родителей. С технической точки зрения ветви - это не более чем значимые имена коммитов. Единственное различие между локальной и удаленной ветками заключается в том, что удаленные ветки с префиксом remoteName/ Git с нуля очень хорошо читаются. Как только вы получите представление о том , как работает Git - и это красиво просто , на самом деле - все просто имеет смысл.
Эмиль Лундберг

13
Большое спасибо за объяснение. До сих пор я не понимал, что Git был разработан, поэтому вам не нужно иметь центральный репозиторий. Все всегда говорят «DVCS» при описании Git, но как относительно новый программист, это ничего не значит для меня. Я никогда не видел CVCS, и я также никогда не работал с центральным удаленным репозиторием, когда работал с другими (например, с Github), поэтому до сих пор я еще не понял, что делает Git особенным.
Брайан Петерсон

7
Итак, исходя из этого, почему не стоит делать git-fetch с работой cron? Всегда рекомендуется хранить копию пульта, с которым вы работаете, на локальном компьютере. На самом деле, мне хочется написать скрипт, который проверяет, обновил ли я свой пульт за последние 24 часа, и связал его с помощью ловушки udev для подключения к интернету.
Брайан Петерсон

24
Одна из причин, почему не стоит работать cron: часто при работе с новым тикетом или при обновлении ветки мне нравится видеть, что изменения выбираются. Если изменения не произойдут во время выборки, я буду более уверенно спрашивать моего коллегу-программиста: «Эй, ты подтолкнул?». Я также чувствую, сколько «оттока» в хранилище с момента последней загрузки. Это также помогает мне понять количество и скорость изменений, которые в настоящее время вносятся в этот репозиторий.
Майкл Даррант

5
@Nabheet Дело в том, что Git ориентирован на контент. Он хранит данные только один раз и указывает на них несколько раз. Вот почему в Git даже несколько коммитов поверх оригинала не сильно влияют на размер репо, так как большинство объектов одинаковы.
cst1992

890

Вот изображение Оливера Стила о том, как все это сочетается :

введите описание изображения здесь

Если есть достаточный интерес, я думаю, я мог бы обновить изображение, чтобы добавить git cloneи git merge...


156
Обновленное изображение с git cloneи git mergeбудет очень полезно!
MEMark

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

12
Одна картинка стоит тысячи слов! Обновленное изображение с потоком данных клонирования и слияния готово где-нибудь? Любой другой поток данных, кроме того, что уже на диаграмме?
Шиханшу

10
@Contango, пожалуйста, добавьте клон и объедините. Было бы полезно для новичков, как я.
арендует

11
Есть две диаграммы, показывающие клон и слияние в других ответах (ниже) от th3sly и the darkpassenger.
intotecho

488

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

git fetch
git diff ...origin

См .: https://git-scm.com/docs/git-diff относительно синтаксиса с двумя и тремя точками в команде diff


9
почему нет git diff ..origin?
Эрик Каплун

3
git diff origin и git diff .. origin, кажется, работает, но не так странно ... материал
Marc

19
@Compustretch Там не должно быть места. git diff ...originэквивалентно git diff $(git-merge-base HEAD origin) origin(см. git diff [--options] <commit>...<commit> [--] [<path>…]раздел kernel.org/pub/software/scm/git/docs/git-diff.html#_description ), которое отличается от git diff origin; git diff ...originэто концептуально изменения, внесенные originс тех пор, как разветвленная текущая ветвь origin, а git diff originтакже включает в себя обратную сторону изменений, внесенных в текущую ветвь с тех пор, как она разветвляется origin.
Макс Нанаси

2
ни одна из команд .. не работает для меня (в Windows), но git diff origin/masterработает, как упомянуто ниже
Брайан Бернс

то же самое здесь, используя git 2.0.0 на OSX. Ни одна из этих команд не сработала. Они устарели?
К.-Майкл Ай

373

Мне стоило немного понять, в чем разница, но это простое объяснение. masterв вашем localhost есть ветка.

Когда вы клонируете репозиторий, вы извлекаете весь репозиторий на свой локальный хост. Это означает, что в то время у вас есть указатель источника / мастера, HEADа мастер указывает на то же самое HEAD.

когда вы начинаете работать и делаете коммиты, вы переводите главный указатель на HEAD+ ваши коммиты. Но указатель источника / мастера все еще указывает на то, что было, когда вы клонировали.

Так что разница будет:

  • Если вы сделаете a, git fetchон просто извлечет все изменения в удаленном хранилище ( GitHub ) и переместит указатель origin / master на HEAD. Тем временем ваш местный руководитель филиала будет продолжать указывать, где он находится.
  • Если вы сделаете a git pull, он в основном извлечет (как объяснено ранее) и объединит любые новые изменения в вашей основной ветке и переместит указатель на HEAD.

14
origin / master - это локальная ветвь, которая является копией master на origin. Когда вы выбираете, вы обновляете local: / origin / master. Как только вы действительно поймете, что все в git - это ветвь, это имеет большой смысл и является очень мощным способом поддержания различных наборов изменений, быстрого локального ветвления, слияния и перебазирования, и, как правило, извлекает большую выгоду из дешевого ветвления. модель.
cam8001

3
Все еще сбивает с толку. Я думал, что git fetchнужно было буквально загружать изменения на удаленном репо в ваше локальное репо, но НЕ фиксировать их, то есть их все равно нужно добавлять / фиксировать в вашем локальном репо.
krb686

3
Получить только извлекает из удаленного / источника (GitHub) в ваше местное происхождение. Но это не объединяет его с вашими фактическими рабочими файлами. если вы сделаете пул, он извлечет и объединит ваши текущие рабочие файлы
Gerardo

223

Иногда помогает визуальное представление.

введите описание изображения здесь


18
Я думаю, что картина должна показать, что это влияет и на местное репо. То есть Git pull - это комбинация влияния на локальный репо и рабочую копию. Прямо сейчас кажется, что это просто влияет на рабочую копию.
неполярность

10
@ 太極 者 無極 而 生 Согласовано - это изображение вводит в заблуждение, потому что выглядит так, будто git pullоно пропускает выборку, что, конечно, неточно.
Форрестхопкинса

9
В чем разница между «Локальным репозиторием» и «Рабочей копией»? Разве они не локальны на компьютере?
theITvideos

1
Какая польза от git fetch тогда? как посмотреть какая разница в локальном репозитории и рабочей копии?
Викаш

2
@theITvideos Нет, это не так. Локальный репозиторий - это место, куда отправляется ваш код (из рабочего репозитория), когда вы фиксируете. (Это происходит в удаленном репо, когда вы нажимаете).
Викаш

219

кратко

git fetchпохоже, pullно не сливается. то есть он получает удаленные обновления ( refsи objects), но ваш локальный остается прежним (то есть origin/masterобновляется, но masterостается тем же).

git pull срывается с пульта и мгновенно сливается.

Больше

git clone клонирует репо.

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

Кроме того, git branch -aпокажет вам точно, что происходит со всеми вашими филиалами - локальными и удаленными.

Этот пост был полезен:

Разница между git pull, git fetch и git clone (и git rebase) - Майк Пирс

и крышки git pull, git fetch,git clone и git rebase.

====

ОБНОВИТЬ

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

  1. Обновите локальное хранилище с удаленного компьютера (но не объединяйте):

    git fetch 
    
  2. После загрузки обновлений давайте посмотрим на различия:

    git diff master origin/master 
    
  3. Если вы довольны этими обновлениями, то объедините:

    git pull
    

Ноты:

На шаге 2: Для получения дополнительной информации о различиях между локальным и удаленным, см .: Как сравнить локальную ветку git с ее удаленной веткой?

На шаге 3: Вероятно, более точно (например, в быстро меняющемся репо) сделать git rebase originздесь. См. Комментарий Джастина Ома в другом ответе.

Смотрите также: http://longair.net/blog/2009/04/16/git-fetch-and-merge/


1
Мне кажется, что если кто-то хочет, чтобы местный код отражал «подсказку», он должен использовать git clone. Я поместил подсказку в кавычки, так как я предполагаю, что это будет означать, какой бы мастер ни был, и что кто-то будет «скачать как zip» с github.com
Крис К

3
Что делать, если вы не довольны изменениями после того, как вы получили Git что делать дальше?
Kugutsumen

Ваш абзац о ребазе был именно тем, что я искал Вся идея обнуления всего, обновления с удаленного компьютера, а затем воспроизведения ваших изменений поверх предыдущих коммитов, которые произошли во время вашей работы. Идеальное объяснение при условии, что это правильно. ;)
coblr

178
git-pull - извлечение и объединение с другим хранилищем или локальной веткой
СИНТАКСИС

мерзавец тянуть ...
ОПИСАНИЕ

Запускает git-fetch с заданными параметрами и вызывает git-merge для объединения 
извлек голову (и) в текущую ветку. С --rebase вызывает git-rebase
вместо мерзавца-слияния.

Обратите внимание, что вы можете использовать. (текущий каталог) в качестве <репозитория> для извлечения
из локального репозитория - это полезно при объединении локальных веток 
в текущую ветку.

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

Вы бы потянули, если хотите, чтобы истории были объединены, вы извлекли бы, если бы вы просто «хотели кодировать», так как кто-то помечал некоторые статьи здесь.


5
Очень интересно, но я действительно не вижу варианта использования, где вы хотите "просто код". И что происходит с вашим кодом при получении? Это стерто? Что происходит при смене пульта? Как это происходит в вашем репо без стирания вашего кода, если вы не объединяетесь?
e-удовлетворительно

11
@ e-sat: Удаленная ветвь также хранится локально на вашем компьютере. Поэтому, когда вы это делаете, git fetchон выбирает изменения из хранилища и обновляет вашу локальную удаленную ветку. Это не влияет на вашу локальную ветку, которая отслеживает локальную удаленную ветку, поэтому не влияет на вашу рабочую копию. Теперь, когда вы сделаете a, mergeон объединит извлеченные изменения с вашей локальной веткой.
Джеффривеон

Простой пример использования команды fetch: выполнять трудоемкие операции, включающие недавние коммиты других людей, такие как слияние или просмотр кода, доступ к вашему актуальному локальному репозиторию без требований к сетевому подключению, поскольку ранее вы использовали fetch для загрузки все, что вам нужно быстро (например, когда вы посещаете какого-то другого разработчика и подключаетесь к какой-либо другой сети репозитория). Команда pull загружает те же самые коммиты, но выполняемое слияние может быть нежелательным.
Лоренцо Гатти,

163

Вы можете получить из удаленного хранилища, увидеть различия, а затем вытащить или объединить.

Это пример для удаленного хранилища с именем originи ветви, которая называется masterотслеживанием удаленной ветви origin/master:

git checkout master                                                  
git fetch                                        
git diff origin/master
git rebase origin master

35
Вы, вероятно, хотите пропустить извлечение и просто сделать «источник git rebase» в качестве последнего шага, так как вы уже получили изменения. Причина в том, что кто-то мог сдвинуть изменения во времени, с тех пор как вы сделали выборку, и они не были бы такими, как вы делали обзор различий.
Джастин Омс

158

Короткий и простой ответ: за 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).


2
@JustinOhms Если git pull --rebaseчто-то не так в данной ситуации, правильно ли это делать в два этапа? Если это правильно, какая польза от этого в два этапа?
Каз

@Kaz - потому что ребаз не автоматический. Извлечение изменений в первую очередь позволяет вам принять решение. Это не решает проблему с перебазированием истории, которую вы уже выдвинули. Это позволит вам увидеть, насколько безопасно отменить изменения, которые вы еще не отправили.
Джастин Омс

2
@JustinOhms Как бы вы решили, насколько безопасно отменить изменения? Я просто попробовал бы git rebase и backtrack, если это сделало беспорядок, и в этом случае я мог бы также сделать git pull --rebase. Но, может быть, у вас есть другой способ?
Каз

3
@KaZ gitk позволяет визуально увидеть структуру ветви. Он покажет вам положение вашего местного руководителя, удаленных сотрудников и структур вашего филиала относительно того, что вы получили. Таким образом, вы можете быть уверены, что не отбрасываете извлеченные изменения, основанные на предке, предшествующем тому, что вы уже отправили на пульт (ы).
Джастин Омс

Используйте, rebaseкогда вы работаете в локальной ветке, которая еще не нажата. Если вы работаете над веткой, которая существует на удаленном компьютере, это rebaseможет привести к некоторым неприятным проблемам, поэтому вы должны предпочесть регулярную merge.
Юстус Ромейн

151

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

мерзкий выбор

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

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

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

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

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

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


мерзавец

Это применяет изменения от удаленного к текущей ветви в локальном ...

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

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

должно быть именем удаленного репозитория, переданным в git-fetch 1 . может называть произвольный удаленный ref (например, имя тега) или даже набор ссылок с соответствующими ветвями удаленного отслеживания (например, refs / head / : refs / remotes / origin / ), но обычно это имя ветки в удаленном репозитории.

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


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

мерзавец и мерзавец


10
Если вам нравится изображение, взгляните на шпаргалку git, которая одинакова для всех команд git ... ndpsoftware.com/git-cheatsheet.html
Том

3
Разве клон также не влияет на локальный репозиторий (копирование всей истории из удаленного)?
Том Лоредо,

135

введите описание изображения здесь

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

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


18
Люди, нажмите на ссылку, чтобы взаимодействовать с различными столбцами. Эта таблица - лучший ресурс, который я видел, чтобы полностью понять различия между командами.
М. Луиза Каррион

Ответ на этот вопрос должен идти к вершине
Tessaracter

126

Бонус:

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

git pull --rebase

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

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

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


4
Хороший совет, хотя для новых пользователей git стоит упомянуть, что rebase изменяет хеши коммитов (я обнаружил, что это удивительно из-за subversion).
AlexMA

1
Можете ли вы объяснить, в чем разница между git pullи git pull --rebase?
Shaijut

2
См. Серьезное предупреждение об этом методе в ответе выше: stackoverflow.com/a/6011169/241244

118

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

                                         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).

Разве git pullтакже не выполняется слияние, то есть переход к рабочей копии?
Kamiel Wanrooij

Хорошо, да, все изменения будут внесены в вашу рабочую копию, а затем вы сможете внести их в локальный репозиторий. Я буду обновлять визуальное.
Юстус Ромейн

@JustusRomijn Разве pull также не обновляет локальный репозиторий? Разве не должно быть звездочки между звездочками источника и рабочей копии?
user764754

2
@ user764754 Когда вы вытягиваете, ваша рабочая копия получает изменения (также могут быть некоторые конфликты, которые вам, возможно, придется решить). Вы все еще должны зафиксировать это в своем локальном хранилище.
Юстус Ромийн

@JustusRomijn: Спасибо за иллюстрацию. Было бы здорово, если бы вы могли сделать диаграмму более полной, иллюстрируя влияние таких операций, как сброс, выбор вишни, на состояния хранилища.
Jith912

106

Я тоже боролся с этим. На самом деле я попал сюда с поиском в 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+               -
---------------------     -----------------------     -----------------------

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


Не так сложно прочитать: блоки представляют состояние репо, которое в каждой строке изменяется во времени слева направо после сообщаемой операции в строке 2 блока. Метки R0n - это теги в git, а тег с + - это еще не загруженный материал. Sanbox используется для вашей рабочей папки, которая отличается от папки репо, где хранятся зафиксированные вещи.
user1708042

96

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

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

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

введите описание изображения здесь

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

введите описание изображения здесь

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

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

введите описание изображения здесь

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

введите описание изображения здесь

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

введите описание изображения здесь


1
если бы вы могли изменить «Основную ветку» на «Удаленное репо», это был бы отличный ответ.
Qibiron, который

87

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

git pull == git fetch + git merge

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

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


3
Я бы лучше сказал git pull == git fetch + git merge:)
Melvynkim

2
Ноgit pull --rebase = git fetch + git rebase
Тино

83

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

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


78

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


73

Git Fetch

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

Git Merge

Вы можете применить изменения, загруженные через fetch, используя команду merge. Merge примет коммиты, полученные из fetch, и попытается добавить их в вашу локальную ветку. Объединение сохранит историю изменений ваших локальных изменений, поэтому, когда вы поделитесь своей веткой с помощью push, Git будет знать, как другие могут объединить ваши изменения.

Git Pull

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


51

Единственная разница между git pullи git fetchзаключается в том, что:

git pull тянет из удаленной ветки и сливает ее.

git fetch только извлекает из удаленной ветки но не сливает

то есть git pull = git fetch + git merge ...


1
И это не поможет, если Git думает, что вы отстали от коммитов и можете «перемотать вперед», что, в конце концов, я закончил rm -rfи начал все сначала. Глупый мерзавец, пожалуйста, просто дай мне знать, чтобы я мог вернуться к работе?
Крис К

47

Проще говоря, если вы собираетесь сесть на самолет без подключения к Интернету ... перед отъездом вы можете просто сделать git fetch origin <master>. Он будет загружать все изменения на ваш компьютер, но держать его отдельно от вашей локальной разработки / рабочей области.

В самолете вы можете внести изменения в свое локальное рабочее пространство, а затем объединить его с тем, что вы получили, и разрешить все возможные конфликты объединения без подключения к Интернету. И если кто-то не внес новые противоречивые изменения в удаленный репозиторий, то, как только вы прибудете в пункт назначения, вы сделаете это git push origin <branch>и отправитесь за кофе.


Из этого удивительного учебника Atlassian :

git fetch загружает коммиты, файлы и ссылки из удаленного репозитория в ваш локальный репозиторий.

Извлечение - это то, что вы делаете, когда хотите увидеть, над чем работают все остальные . Это похоже на обновление SVN в том, что оно позволяет вам видеть, как продвигается центральная история, но не заставляет вас фактически объединять изменения в вашем хранилище. Git изолирует извлеченный контент как от существующего локального контента , это абсолютно не влияет на вашу локальную работу по разработке . Извлеченное содержимое должно быть явно извлечено с помощью git checkoutкоманды. Это делает выборку безопасного способа просмотра коммитов перед их интеграцией в локальный репозиторий.

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


С git pull:

  • Вы не получаете никакой изоляции.
  • Это влияет на ваше местное развитие.
  • Это не должно быть явно проверено. Потому что это неявно делает git merge.
  • Это в основном НЕ безопасно. Это агрессивно
  • В отличие от , git fetchгде она влияет только на .git/refs/remotes, мерзавец тянуть будет влиять как ваш .git/refs/remotes и .git/refs/heads/

Хм ... так что, если я не обновляю рабочую копию git fetch, то где я делаю изменения? Где Git выбирает новые коммиты?

Отличный вопрос Он помещает его куда-то изолированно от вашей рабочей копии. Но опять же где? Давайте выясним.

В каталоге вашего проекта (то есть, где вы делаете свои gitкоманды) выполните:

  1. ls, Это покажет файлы и каталоги. Ничего крутого, я знаю.

  2. Теперь делай ls -a. Это покажет точечные файлы , то есть файлы , начинающиеся с .вы затем сможете увидеть каталог с именем: .git.

  3. Есть cd .git. Это, очевидно, изменит ваш каталог.
  4. Теперь самое интересное; делать ls. Вы увидите список каталогов. Мы ищем refs. Есть cd refs.
  5. Интересно посмотреть, что находится внутри всех каталогов, но давайте сосредоточимся на двух из них. headsи remotes. Используйте, cdчтобы проверить внутри них тоже.
  6. Все, git fetch что вы делаете, будет обновлять элементы в /.git/refs/remotesкаталоге. Это не будет ничего обновлять в /.git/refs/headsкаталоге.
  7. Любой git pull сначала сделает git fetch, обновит элементы в /.git/refs/remotesкаталоге, затем объединится с вашим локальным, а затем изменит заголовок внутри /.git/refs/headsкаталога.

Очень хороший ответ на этот вопрос также можно найти в разделе Где размещается «git fetch»? ,

Кроме того, ищите «Слеш нотацию» из поста соглашения о наименовании веток Git . Это поможет вам лучше понять, как Git размещает вещи в разных каталогах.


Чтобы увидеть реальную разницу

Просто делать:

git fetch origin master
git checkout master

Если удаленный мастер был обновлен, вы получите следующее сообщение:

Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Если вы этого не сделали fetchи сделали, git checkout masterто ваш местный мерзавец не знал бы, что добавлено 2 коммита. И было бы просто сказать:

Already on 'master'
Your branch is up to date with 'origin/master'.

Но это устаревшее и неправильное. Это потому, что git даст вам обратную связь исключительно на основе того, что он знает. Он не обращает внимания на новые коммиты, которые еще не снесены ...


Есть ли способ увидеть новые изменения, сделанные в удаленном режиме при локальной ветке?

Некоторые IDE (например, XCode) очень умны и используют результат a git fetchи могут комментировать строки кода, которые были изменены в удаленной ветви вашей текущей рабочей ветви. Если эта строка была изменена как локальными изменениями, так и удаленной ветвью, то эта строка помечается красным. Это не конфликт слияния. Это потенциальный конфликт слияния. Это headps, который вы можете использовать для разрешения будущего конфликта слияния, прежде чем делать это git pullиз удаленной ветви.

введите описание изображения здесь


Интересный совет:

Если вы загрузили удаленную ветку, например, сделали:

git fetch origin feature/123

Тогда это будет идти в ваш каталог удаленных. Это все еще не доступно для вашего локального каталога. Тем не менее, это упрощает вашу проверку в этой удаленной ветви с помощью DWIM (делайте то, что я имею в виду):

git checkout feature/123

вам больше не нужно делать:

git checkout -b feature/123 origin/feature/123

Подробнее об этом читайте здесь


1
Мне нравится этот ответ
Kid_Learning_C

44

Git позволяет применять хронологически более старые коммиты после новых коммитов. Из-за этого процесс передачи коммитов между репозиториями делится на два этапа:

  1. Копирование новых коммитов из удаленной ветви в копию этой удаленной ветви внутри локального репо.

    (репо к операции репо) master@remote >> remote/origin/master@local

  2. Интеграция новых коммитов в локальный филиал

    (операция внутреннего репо) remote/origin/master@local >> master@local

Есть два способа сделать шаг 2. Вы можете:

  1. Разветвите локальную ветвь после последнего общего предка и добавьте новые коммиты, параллельные коммитам, которые являются уникальными для локального репозитория, завершаются объединением коммитов, закрывая форк.
  2. Вставить новые коммиты после последнего общего предка и повторно применить коммиты, уникальные для локального репозитория.

В gitтерминологии шаг 1 есть git fetch, шаг 2 это git mergeилиgit rebase

git pullэто git fetchиgit merge


37

Git получает ветку последней версии с удаленного на локальный с помощью двух команд:

  1. git fetch: Git собирается получить последнюю версию с удаленной на локальную, но она не объединяется автоматически.      git fetch origin master git log -p master..origin/master git merge origin/master

         Приведенные выше команды означают, что вы загружаете последнюю версию основной ветви из источника из удаленной в исходную главную ветку. А затем сравнивает локальную главную ветку и главную ветку происхождения. Наконец, слияние.

  2. git pull: Git собирается получить последнюю версию с пульта и слиться с локальной.

        git pull origin master

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


37

В чем разница между git pullи git fetch?

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

git fetchобновляет локальную копию удаленного хранилища. Например, если вашим удаленным репозиторием является GitHub, вы можете извлечь любые изменения, сделанные в удаленном репозитории, в свою локальную копию этого удаленного репозитория. Это позволит вам выполнять такие операции, как сравнение или слияние.

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


35

git pull == (git fetch + git merge)

git fetch не меняется на локальные ветки.

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


34

Пытаться быть понятным и простым.

Команда git pull на самом деле является командой shortcutfor git fetch, за которой следует команда git merge или команда git rebase, в зависимости от вашей конфигурации. Вы можете настроить свой Git-репозиторий так, чтобы git pull представлял собой выборку с последующей ребазой.


33

Простое графическое представление для начинающих,

введите описание изображения здесь

Вот,

git pull  

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

но в ,

мерзкий выбор

будет извлекать код из хранилища, и нам нужно перебазировать его вручную, используя git rebase

Например: я собираюсь получить от мастера сервера и перебазировать его в моем локальном мастере.

1) git pull (ребаз будет выполнен автоматически):

git pull origin master

здесь origin - ваш удаленный репо, master - ваша ветка

2) git fetch (нужно перебазировать вручную):

git fetch origin master

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

git rebase origin/master

это перебазирует код в локальный. перед этим убедитесь, что вы находитесь в правильном направлении.


Хороший график, но вы можете объяснить, почему вы используете «rebase», когда график говорит «слияние».
Гунтрам Блом поддерживает Монику

2
merge будет представлять другой коммит ветви и генерировать новый коммит, который содержит коммиты в качестве ссылки. но rebase будет реплицировать коммиты из другой ветки, но не будет создавать новый коммит, а не копировать
Mohideen bin Mohammed

33

На самом деле Git поддерживает копию вашего собственного кода и удаленного хранилища.

Команда git fetchобновляет локальную копию, получая данные из удаленного хранилища. Причина, по которой мы нуждаемся в этом, заключается в том, что кто-то еще мог внести некоторые изменения в код, и вы хотите постоянно обновляться.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.