Яка різниця між "git pull" та "git fetch"?


11911

Які відмінності між git pullі git fetch?


364
Я знайшов цю добре написану статтю про git fetch та git pull, яку варто прочитати: longair.net/blog/2009/04/16/git-fetch-and-merge
Marcos Oliveira

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

26
Переконайтеся, що ви знаєте, як правильно використовувати git stash. Якщо ви питаєте про «тягнути» і «принести» , то може бути «тайник» також потрібно пояснювати ...
Генрі Heleine

36
Багато людей, які приїжджають з Mercurial, продовжують використовувати "git pull", думаючи, що це еквівалент "hg pull". Що це не так. Еквівалент Git "hg pull" - "git fetch".
Серж Шульц

8
команда git fetch отримує оновлений код із гілкою, а також отримує нещодавно додані гілки у вашому локальному регіоні, команда git pull отримує лише оновлений код поточної гілки
Kartik Patel

Відповіді:


9914

Простіше кажучи, git pullчи git fetchслідує a git merge.

Ви можете зробити в git fetchбудь-який час, щоб оновити свої відділення віддаленого відстеження під refs/remotes/<remote>/.

Ця операція ніколи не змінює будь-які ваші власні місцеві відділення під refs/heads, і це безпечно робити без зміни вашої робочої копії. Я навіть чув про людей, які git fetchперіодично виконують роботу з кроном у фоновому режимі (хоча я б не рекомендував це робити).

A git pull- це те, що ви зробите для того, щоб оновити локальну гілку з її віддаленою версією, а також оновити інші гілки віддаленого відстеження.

Документація Git - git pull :

У режимі за замовчуванням git pullце стенограма, за git fetchякою слід git merge FETCH_HEAD.


326
"" Витягнення git "- це те, що ви зробили б для того, щоб оновити свій сховище" <- чи не оновлення репозиторію вже зроблено користувачем? ви не маєте на увазі, що він приносить ваші місцеві відділення в ногу з віддаленими гілками? До злиття: він об'єднує віддалені гілки з вашими локальними копіями цих гілок, або що саме тут зливається?
Альберт

194
@Albert: Так, це дивно сформульовано. 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з іншого боку, швидко пересилаю мою гілку відстеження.
Роман Старков

2170
  • Під час використання pullGit намагається автоматично зробити вашу роботу за вас. Це залежно від контексту , тому Git об'єднає будь-які витягнуті комісії у гілку, в якій ви зараз працюєте. pull Автоматично об’єднує комісії, не даючи вам спочатку їх переглянути . Якщо ви не дуже близько керуєте своїми філіями, у вас можуть виникнути часті конфлікти.

  • Коли ви fetch, Git збирає будь-які комісії з цільової гілки, які не існують у вашому поточному відділенні, і зберігає їх у вашому локальному сховищі . Однак це не об'єднує їх із вашою нинішньою галуззю . Це особливо корисно, якщо вам потрібно постійно оновлювати сховище, але ви працюєте над тим, що може зламатися, якщо ви оновите свої файли. Щоб інтегрувати коміти у свою головну галузь, ви використовуєте merge.


34
Погоджено, чудовий коментар. Тому я ненавиджу git pull. Коли коли-небудь буде сенс дозволити інструменту редагування вносити зміни для коду для вас? І хіба це не те, що робить об'єднання двох файлів? Що робити, якщо ці два зміни фізично розділені у файлі, але ЛОГІЧНО розбігається?
Лі Діксон

126
@elexhobby коротко кажучи, git fetchоновлює лише ваш .git/каталог (AKA: локальний сховище) і нічого поза .git/(AKA: робоче дерево). Це не змінює ваші місцеві відділення, і це не торкається masterтакож. Це зачіпає remotes/origin/masterхоч (див. git branch -avv). Якщо у вас більше дистанційних, спробуйте git remote update. Це git fetchдля всіх дистанційних в одній команді.
Тіно

24
@Tino ваш - це справді найважливіший момент. Люди можуть не знати, що "віддалені" гілки насправді зберігаються як купа хешей .git/refs/remotes/origin/.
Кріс

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

13
@Tino Що я досі не розумію - це сенс? Навіщо використовувати добір, якщо він лише оновлюється .git? Яка передбачувана вигода і що я повинен робити після цього?
BadHorsie

1210

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

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

Git був розроблений для підтримки більш розповсюдженої моделі без потреби в центральному сховищі (хоча ви, звичайно, можете скористатися нею, якщо вам подобається). Також git був розроблений так, що клієнту та "серверу" не потрібно одночасно бути в мережі. Git був розроблений так, щоб люди на ненадійному посилання могли обмінюватися кодом навіть електронною поштою. Можна працювати повністю відключеним і записувати компакт-диск для обміну кодом через 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

888

Ось образ Олівера Стіла про те, як все це поєднується разом :

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

Якщо є достатній інтерес, я думаю, я міг би оновити зображення, щоб додати git cloneта git merge...


156
Оновлене зображення з git cloneі git mergeбуде дуже корисно!
ПАМ'ЯТ

20
Так, будь ласка, додайте git merge- це повинно чітко показувати, що mergeвиклик окремо НЕ тотож, як дзвінок, pullтому що pullзливається лише з віддаленого і ігнорує ваші локальні комісії у вашій місцевій філії, яка відстежує віддалену гілку.
JustAMartin

12
Картина варта тисячі слів! Чи готове десь готове оновлене зображення з клонуванням та об'єднанням потоку даних? Будь-який інший потік даних, крім того, що вже є на схемі?
shikhanshu

10
@Contango, будь ласка, додайте клон та об'єднайте. Були б корисні для новачків, як я.
орендна плата

11
Є дві діаграми, що показують клонування та злиття в інших відповідях (нижче) th3sly та thedarkpassenger.
інтохо

488

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

git fetch
git diff ...origin

Дивіться: https://git-scm.com/docs/git-diff щодо синтаксису подвійних та трійкових точок у команді diff


9
чому ні git diff ..origin?
Ерік Каплун

3
git diff походження та git diff .. абориген, здається, працює, але не це дивно ... речі
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у вашому локальному господарстві є філія.

Коли ви клонуєте сховище, ви отримуєте весь сховище для вашого локального хоста. Це означає, що на той час у вас є початковий / головний вказівник на HEADта головний вказівник на те саме HEAD.

коли ви почнете працювати і виконувати зобов’язання, ви пересунете головний вказівник на HEAD+ ваші коміти. Але вказівник початок / головний все ще вказує на те, що було під час клонування.

Отже різниця буде:

  • Якщо ви зробите git fetchце, ви просто отримаєте всі зміни у віддаленому сховищі ( GitHub ) і перемістіть початковий / головний вказівник на HEAD. Тим часом ваш місцевий майстер відділення буде постійно вказувати, де він є.
  • Якщо ви зробите це git pull, воно в основному вийде (як було пояснено раніше) і об'єднає будь-які нові зміни у вашу головну гілку та перемістить вказівник на HEAD.

14
origin / master - це локальна галузь, яка є КОПІЮЮ майстра по походженню. Коли ви отримуєте, ви оновлюєте локальний: / origin / master. Після того, як ви дійсно подумаєте, що все в git - це галузь, це має багато сенсу і є дуже потужним способом підтримувати різні набори змін, робити швидкі локальні гілки, об’єднувати та перезавантажуватись і, як правило, отримувати багато цінності з дешевого розгалуження. модель.
cam8001

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

3
Витягуйте лише ті, що віддаляються від віддаленого / походження (github) до вашого місцевого походження. Але це не об'єднує його з вашими фактичними робочими файлами. якщо ви потягнете, це дістанеться і злиття з вашими поточними робочими файлами
Джерардо,

223

Іноді допомагає візуальне уявлення.

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


18
Я думаю, що картина мала показати, що вона впливає і на місцеве репо. Тобто, Git pull - це поєднання впливу на місцеве репо та робочу копію. Зараз, здається, це просто впливає на робочу копію.
неополярність

10
@太極者無極而生Погоджено - це зображення дуже вводить в оману, тому що це робить його схожим на git pullце пропуск вибірки, який, звичайно , є неточною.
forresthopkinsa

9
в чому різниця між "локальним сховищем" та "робочою копією"? Чи не обидва вони локальні на комп’ютері?
theITvideos

1
Яка користь від отримання git fetch? як побачити, яка різниця є в локальному сховищі та робочій копії?
Вікаш

2
@theITvideos Ні, це не так. Місцеве сховище - це куди відправляється ваш код (з робочого сховища) під час здійснення. (Коли ви натискаєте, він переходить до віддаленого репо.
Вікаш

219

Коротко

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.

====

ОНОВЛЕННЯ

Я думав би оновити це, щоб показати, як ви насправді використовуєте це на практиці.

  1. Оновіть локальне репо з дистанційного (але не зливайтеся):

    git fetch 
    
  2. Завантаживши оновлення, давайте подивимося на відмінності:

    git diff master origin/master 
    
  3. Якщо ви задоволені цими оновленнями, тоді об'єднайте:

    git pull
    

Примітки:

На кроці 2: Докладніше про відмінності між локальним та віддаленим див. У розділі: Як порівняти локальну гілку git із віддаленою гілкою?

На кроці 3: Мабуть, точніше (наприклад, на репо, що швидко змінюється) зробити git rebase originтут. Дивіться коментар @Justin Ohms в іншій відповіді.

Дивіться також: http://longair.net/blog/2009/04/16/git-fetch-and-merge/


1
Мені здається, якщо хтось просто хоче, щоб локальний код відображав "підказку", він повинен використовувати git clone. Я поклав підказки в лапки, тому що я припускаю, що це означатиме, що майстер є, і що хтось "скача як zip" з github.com
Кріс К

3
що робити, якщо ви не задоволені змінами після того, як ви отримаєте збір? що робити далі?
Кугуцумен

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

178
git-pull - витягнути з іншого сховища чи локальної гілки та об’єднати його
СИНОПИС

git pull ...
ОПИС

Запускає git-fetch із заданими параметрами та викликає git-merge для об'єднання 
отримані голови (-и) у поточну гілку. З --rebase, викликає git-rebase
замість git-merge.

Зверніть увагу, що ви можете використовувати. (поточний каталог) як <репозиторій>, який потрібно витягнути
з локального сховища - це корисно при об'єднанні локальних гілок 
в поточну галузь.

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

Ви б потягнули, якщо хочете, щоб історії злилися, ви б прийшли, якщо просто "хочете кодек", як хтось позначав тут статті.


5
Дуже цікаво, але я не можу реально побачити випадок використання, де потрібно "лише код". І що відбувається з вашим кодом, коли ви отримуєте його? Чи стирається? Що відбувається з віддаленими змінами? Як це потрапляє у ваше репо, без стирання вашого коду, якщо ви його не зливаєте?
e-satis

11
@ e-satis: Віддалене відділення також зберігається локально на вашій машині. Отже, коли ви git fetchце робите, ви отримуєте зміни зі сховища та оновлює локальну віддалену гілку. Це не впливає на вашу місцеву гілку, яка відстежує локальну віддалену гілку, тому не впливає на вашу робочу копію. Тепер, коли ви зробите mergeце, ви з’єднаєте отримані зміни з вашою локальною гілкою.
jeffreyveon

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

163

Ви можете отримати з віддаленого сховища, побачити відмінності, а потім витягнути або об'єднати.

Це приклад віддаленого сховища, що називається, originі гілки під назвою masterвідстеження віддаленої гілки origin/master:

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

35
Ви, ймовірно, хочете пропустити потяг і просто зробити "походження ребатів git" як останній крок, оскільки ви вже отримали зміни. Причина полягає в тому, що хтось міг підштовхнути зміни за час, коли ви зробили забір, і вони не були б у виборі, щоб ви зробили розгляд розгляду.
Джастін Омс

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, і, якщо б це зробило безлад, я б міг зробити зворотній зв'язок, і тоді я міг би також зробити git pull --rebase. Але, можливо, у вас є інший шлях?
Каз

3
@KaZ gitk дозволяє візуально бачити структуру гілки. Він покаже ваше місце місцевого голови, віддалені та ваші гілкові структури стосовно того, що ви отримали. Таким чином, ви можете переконатися, що ви не будете отримувати винайдені зміни, засновані на предку, що передує тому, що ви вже натиснули на ваш віддалений (и).
Джастін Омс

Використовуйте, rebaseколи ви працюєте на локальній гілці, яка ще не натиснута Якщо ви працюєте у відділенні, яке існує у віддаленому режимі, це rebaseможе спричинити за собою деякі неприємні проблеми, тому вам слід віддавати перевагу звичайній merge.
Юстус Ромійн

151

ОК , ось деяка інформація про git pullта git fetch, таким чином Ви можете зрозуміти реальні відмінності ... в декількох простих словах, вибірка отримує останні дані, але не зміни коди і не збираюся возитися з поточним локальним кодом гілки, але тягнути прибуде код змінюється і об'єднуйте його з вашим місцевим відділенням, читайте далі, щоб отримати докладнішу інформацію про кожен:

git fetch

Він завантажить усі реф і об’єкти та будь-які нові відділення у ваш локальний сховище ...

Вилучення гілок та / або тегів (разом "refs") з одного або декількох інших сховищ, а також об'єктів, необхідних для завершення їх історії. Гілки віддаленого відстеження оновлюються (див. Опис нижче щодо способів контролю такої поведінки).

За замовчуванням також отримується будь-який тег, який вказує на витягнуті історії; ефект полягає в тому, щоб отримати теги, які вказують на гілки, які вас цікавлять. Цю поведінку за замовчуванням можна змінити, скориставшись параметрами --tags або --no-tags або налаштувавши віддалений..tagOpt. Використовуючи refspec, який чітко отримує теги, ви можете отримати теги, які також не вказують на гілки, які вас цікавлять.

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

Якщо не вказано пульт дистанційного керування, за замовчуванням буде використовуватися віддалений вихідний код, якщо немає поточної гілки, налаштованої вище.

Імена отриманих посилань разом із іменами об'єктів, на які вони вказують, записуються у .git / FETCH_HEAD. Ця інформація може використовуватися скриптами або іншими командами git, такими як git-pull.


git pull

Він застосує зміни від віддаленого до поточної гілки в локальному ...

Включає зміни з віддаленого сховища в поточну гілку. У режимі за замовчуванням git pull є скороченням для git fetch з подальшим об'єднанням git FETCH_HEAD.

Точніше, git pull запускає git fetch із заданими параметрами і викликає git merge для об'єднання отриманих головок гілок у поточну гілку. З --rebase, він запускає git rebase замість git spajanje.

має бути назвою віддаленого сховища, переданого git-fetch 1 . Ви можете назвати довільну віддалену відмову (наприклад, ім'я тегу) або навіть колекцію рефератів із відповідними гілками віддаленого відстеження (наприклад, refs / heads / : refs / remotes / origin / ), але зазвичай це ім'я відділення у віддаленому сховищі.

Значення за замовчуванням для та зчитуються з конфігурації "віддаленого" та "злиття" для поточної гілки, встановленої git-branch --track.


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

git pull і git fetch


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

3
Чи не впливає клонування також на локальне сховище (копіювання всієї історії з віддаленого)?
Том Лоредо

135

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

Це інтерактивне графічне зображення дуже корисне для розуміння git: http://ndpsoftware.com/git-cheatsheet.html

git fetchпросто "завантажує" зміни з віддаленого у ваше місцеве сховище. git pullзавантажує зміни та об'єднує їх у вашу поточну гілку. "У режимі за замовчуванням - git pullце стенограма для git fetchякої git merge FETCH_HEAD."


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

Цю відповідь потрібно пройти до вершини
Tessaracter

126

Бонус:

Говорячи про витягнення та отримання вищенаведених відповідей, я хотів би поділитися цікавою хитрістю

git pull --rebase

Ця вище команда - найкорисніша команда в моєму житті git, яка зекономила багато часу.

Перш ніж натиснути на сервер свої нові зобов’язання, спробуйте цю команду, і вона автоматично синхронізує останні зміни на сервері (з вилученням і злиттям) і поставить ваші зобов’язання вгорі в журналі git. Не потрібно турбуватися про ручне потягування / злиття.

Деталі можна знайти на веб- сайті: http://gitolite.com/git-pull--rebase


4
Хороший підказник, хоча варто згадати новим користувачам git, які перезавантажують модулі змінюють хеші (я виявив, що дивовижне надходить від підриву).
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 Чи не потяг також не оновлює локальне сховище? Чи не повинно бути зірочка між оригіналом та зірочками робочої копії?
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 використовується для вашої робочої папки, яка відрізняється від папки repo, де зберігаються зафіксовані речі.
user1708042

96

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

Візьмемо приклад того, що ви працюєте над проектом зі своїми членами команди. Таким чином, їх буде однією з головних гілок проекту, і всі учасники проекту повинні подати його до власного локального сховища, а потім працювати над цією локальною гілкою, щоб змінити / додати модулі, а потім повернутися до основної гілки.

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

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

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

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

Щоб уникнути подібних питань та працювати паралельно початковому прогресу проекту, це два способи:

1. Git Fetch - це завантажить усі зміни, внесені до початкового / основного галузевого проекту, які відсутні у вашій місцевій філії. І буде чекати, коли команда Git Merge застосує зміни, отримані у вашому сховищі або відділенні.

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

Тож тепер Ви можете ретельно контролювати файли, перш ніж об'єднати їх у свій сховище. Ви також можете змінити, Dякщо потрібно, через змінену C.

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

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

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


1
якщо ви можете змінити "Головну гілку" на "Віддалене репо", це буде чудовою відповіддю.
Цибірон Хто

87

Ми просто кажемо:

git pull == git fetch + git merge

Якщо ви запускаєте git pull, вам не потрібно об’єднувати дані з локальними. Якщо ви запустите git fetch, це означає, що ви повинні запустити git mergeдля отримання останнього коду на вашу локальну машину. В іншому випадку локальний код машини не буде змінено без злиття.

Отже, в Git Gui, коли ви робите, ви повинні об'єднати дані. Вибір сам не змінить код у вашому регіоні. Ви можете перевірити, коли ви оновлюєте код, отримуючи один раз його отримання та переглядайте; код він не змінить. Потім ви зливаєтесь ... Ви побачите змінений код.


3
Я краще скажу git pull == git fetch + git merge:)
мельвінким

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буде запущено вилучення на віддаленому відрізку, відстежуваному поточною гілкою, а потім об'єднає результат. Ви можете git fetchперевірити, чи є оновлення віддаленої гілки без необхідності їх об’єднання з місцевою гілкою.


73

Git Fetch

Ви завантажуєте зміни до своєї місцевої філії з походження через завантаження. Fetch просить у віддаленого РЕПО всіх зобов’язань, які зробили інші, але у вас немає місцевого репо. Отримати завантаження цих комісій та додавання їх до локального сховища.

Git Merge

Ви можете застосувати зміни, завантажені через виборку, за допомогою команди злиття. Злиття візьме комісії, отримані з завантаження, і спробує додати їх до вашої місцевої філії. Злиття збереже історію фіксації ваших локальних змін, так що коли ви поділитесь вашою філією із натисканням, Git дізнається, як інші можуть об’єднати ваші зміни.

Git Pull

Вилучення та злиття виконуються разом досить часто, щоб була створена команда, що поєднує в собі два, тягнути. Потягніть виконує завантаження, а потім об'єднання для додавання завантажених комісій у вашу локальну філію.


52

Єдина різниця між git pullі git fetchполягає в тому, що:

git pull тягне з віддаленої гілки і зливає її.

git fetch виймається лише з віддаленої гілки, але вона не зливається

тобто git pull = git fetch + git merge ...


1
І не допоможе, якщо git думає, що ти відстаєш від домовленостей і можеш "перемотатись вперед", що після того, як я закінчився rm -rfцілою справою і почав спочатку . Дурний Гіт, будь ласка, дозволь мені дати ток, щоб я міг повернутися до роботи?
Кріс К

46

Простіше кажучи, якщо ви збиралися скокнути на літак без будь-якого з’єднання з Інтернетом ... перед від'їздом ви могли просто зробити git fetch origin <master>. Це дозволило б отримати всі зміни на вашому комп'ютері, але тримайте його окремо від локальної розробки / робочої області.

У площині ви можете внести зміни до місцевого робочого простору, а потім об'єднати його з тим, що ви отримали, і вирішити потенційні конфлікти злиття, без підключення до Інтернету. І якщо хто - то не зробили нові зміни конфліктуючих в віддалене сховище , то після прибуття в пункті призначення ви могли б зробити git push origin <branch>і піти отримати кави.


З цього дивовижного підручника з атласу :

У 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 вплине як на ваше, так і на ваше.git/refs/remotes .git/refs/heads/

Гммм ... так що якщо я не оновлюю робочу копію git fetch, то де я вношу зміни? Де Git fetch зберігає нові зобов’язання?

Чудове запитання. Він розміщує його десь ізольовано від вашої робочої копії. Але знову ж де? Давай дізнаємось.

У каталозі вашого проекту (тобто, де ви виконуєте свої 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"? .

Крім того, шукайте "Slash notation" з гілки 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то ваш місцевий git не знав би, що додано 2 коміти. І це просто сказало б:

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

Але це застаріло і неправильно. Це тому, що git надасть вам відгук виключно на основі того, що він знає. Це не забуває про нові зобов'язання, які ще не знищили ...


Чи є можливість побачити нові зміни, внесені у віддалений під час роботи на філії локально?

Деякі IDE (наприклад, Xcode) є надзвичайно розумними та використовують результат a git fetchі можуть коментувати рядки коду, які були змінені у віддаленому відділенні поточної робочої гілки. Якщо цей рядок було змінено як локальними змінами, так і віддаленою гілкою, то цей рядок буде помічено червоним кольором. Це не конфлікт злиття. Це потенційний конфлікт злиття. Це заголовок, який можна використовувати для вирішення майбутнього конфлікту злиття, перш ніж робити 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


36

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можливо, більш безпечно, тому що перед об'єднанням ми можемо побачити зміни та вирішити, чи слід об'єднувати.


36

У чому різниця між git pullі git fetch?

Щоб зрозуміти це, спочатку потрібно зрозуміти, що ваш локальний git підтримує не лише ваше локальне сховище, але він також підтримує локальну копію віддаленого сховища.

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

git pullз іншого боку, приведе зміни у віддаленому сховищі, де ви зберігаєте власний код. Як правило, спочатку git pullзробіть git fetchактуальну локальну копію віддаленого сховища, а потім об'єднає зміни у ваше власне сховище коду та, можливо, вашу робочу копію.


34

git pull == (git fetch + git merge)

git fetch не змінюється на місцеві гілки.

Якщо у вас вже є локальне сховище з віддаленим налаштуванням для потрібного проекту, ви можете схопити всі гілки та теги для існуючого віддаленого за допомогою git fetch. ... Вибір не вносить жодних змін до місцевих гілок, тому вам потрібно буде об'єднати віддалену гілку з парною локальною гілкою, щоб включити нові зміни. з github


33

Намагаючись бути зрозумілим і простим.

Команда git pull - це фактично shortcutдля git fetch, за яким слідує git merge або команда gbase rebase, залежно від вашої конфігурації. Ви можете налаштувати своє сховище Git таким чином, щоб git pull був результатом, за яким слідує повторна база даних.


33

Просте графічне зображення для початківців,

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

тут,

git pull  

вилучить код із сховища та перезавантажить ваш локальний ... у git pull існує можливість створення нових комітетів.

але в,

git fetch

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

наприклад: я збираюся взяти з майстра сервера і відновити його в моєму локальному майстрі.

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

git pull origin master

тут походження - ваш віддалений майстер репо - ваша філія

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

git fetch origin master

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

git rebase origin/master

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


Хороший графік, але ви, можливо, захочете пояснити, чому ви використовуєте "rebase", коли на графіку написано "об'єднати".
Гунтрам Блом підтримує Моніку

1
Злиття буде представляти собою інший філіальний комітет і створить новий комітет, який містить комісії як посилання. але Rebase буде повторювати комісії з іншої гілки, вона не буде створювати нову
комісію,

33

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

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.