git fetch + git merge origin / master против git pull origin / master

Я думал, что git pull похож на слияние git fetch + git. Находясь в BranchA, я всегда делаю git fetch, а затем git merge origin / master. Но сегодня, находясь в BranchA, я попробовал git pull origin / master, и это не сработало, но сработало выполнение git pull origin master. Есть предположения?

Дополнительный вопрос: если обновленное происхождение / мастер и онлайн-версия мастера совпадают, зачем беспокоиться о происхождении / мастере, не было бы удобнее всегда работать с онлайн-версией, которая всегда обновляется, освобождая нас от бремя, чтобы всегда быть git fetching?


person user33276346    schedule 14.04.2020    source источник
comment
Не могли бы вы объяснить, как это не сработало?   -  person Jona    schedule 14.04.2020
comment
Отвечает ли это на ваш вопрос? Различия между git pull origin master и git pull origin / master   -  person phd    schedule 14.04.2020
comment
stackoverflow.com/   -  person phd    schedule 14.04.2020


Ответы (1)


Я думал, что git pull похож на слияние git fetch + git.

Это. Однако синтаксис, который используется с git pull, не соответствует синтаксису, который используется практически со всеми другими командами Git. Это связано с историей: git pull предшествует ряду улучшений, сделанных в Git между версиями Git до 1.5 и после 1.6. (Обратите внимание, что Git сейчас имеет версию 2.26, так что это действительно древняя история, восходящая к 2005 году или около того. Самые старые версии Git, которые люди, похоже, все еще используют сегодня, находятся в диапазоне версий 1.7, но когда вы запускаете git pull, вы возвращаемся к докаменному веку, эпохе динозавров Git 1.5.)

[но] Я попробовал git pull origin/master, и это не сработало [пока] git pull origin master работало

Это потому, что это специальный синтаксис только для git pull.

Внимательно прочтите git pull документацию на предмет исключений (которых много), но в целом , большинство аргументов, которые вы передаете git pull, git pull передается git fetch. Так же, как вы бы не побежали:

git fetch origin/master      # wrong

ты не можешь бежать

git pull origin/master       # also wrong: this runs git fetch origin/master

Однако вы можете запустить:

git fetch origin master

Здесь origin - удаленный, а master - refspec (см. git fetch документацию, чтобы узнать больше о пультах дистанционного управления и технических характеристиках). Это, в частности, ограничивает вашу git fetch операцию выборкой только новых коммитов, которые находятся на их master, чтобы обновлять только ваш origin/master. 1

После завершения выборки pull запускает merge или, если вы так указали, rebase на некотором наборе коммитов ветвления. 2 Общая идея здесь - которая восходит к тому, что было до Git-1.6 История, о которой я упоминал, заключается в том, что, получив некоторые коммиты из другого Git, вы теперь хотите включить эти коммиты в свою текущую ветку.

В раннем Git было время, когда не существовало всей концепции удаленного, и, следовательно, не существовало имен удаленного отслеживания: не было origin вообще, а значит, не было origin/master. Поэтому было важно включить их коммиты немедленно, чтобы ваш Git не запустил сборку мусора и удалил новые полученные вами коммиты.

В эпоху после 1.6 - то есть с 2006 года или около того - было безопасно собирать коммиты и позволять им сидеть некоторое время, пока вы их просматриваете, думаете о них или даже игнорируете их целиком на какое-то время. В удаленном имени origin представлены имена удаленного отслеживания, например origin/master, которые сохраняют эти фиксации на неопределенный срок. Больше нет необходимости в безумной спешке ссовывать эти коммиты в одну из ваших собственных веток, чтобы предотвратить их удаление.

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


1 Этот вид git fetch обновит ваш origin/master в любом современном Git, но в версиях Git до 1.8.4 он оставит origin/master не обновленным.

2 Коммиты, выбранные в качестве аргументов для слияния или перебазирования, взяты из ссылок, которые вы специально указали в командной строке, если вы указали какие-либо из них. В противном случае (одиночная) фиксация, выбранная в качестве аргумента, соответствует настройке восходящего потока текущей ветви.

В некоторых случаях git pull запускает что-то, кроме слияния или перебазирования, в качестве второй команды. Самый интересный из этих частных случаев - это втягивание в полностью пустой репозиторий: здесь ни git merge, ни git rebase ничего не будут делать, поэтому git pull по сути просто запускает git checkout. Этот особый случай, очевидно, случается только один раз в любом заданном репозитории.

person torek    schedule 14.04.2020
comment
Если я сделаю git pull, он будет git fetch (обновит мои origin / x) и git merge origin / master только для моей ветки. С другой стороны, если я сделаю git pull origin master, он будет git fetch (обновит только мой origin / master) и git merge origin / master только для моей ветки. Верны ли эти предположения? - person user33276346; 15.04.2020
comment
@ user33276346: без дополнительных аргументов, т. е. при запуске как git pull, ваш Git будет искать параметр восходящего потока для вашей текущей ветки. В какой ветке ты? Что это за апстрим? Разбейте это на части - например, origin/master становится origin master, и первая часть дает вам пульт для git fetch. Соедините их вместе, и они дадут вам имя удаленного отслеживания для следующего git merge. Выполняемая git pull выборка будет неограниченной, обновляющей origin/*. - person torek; 16.04.2020
comment
Но с дополнительными аргументами, например git pull origin master, ваш Git будет запускать git fetch origin master, который представляет собой ограниченную выборку, которая просто обновляет ваш origin/master. Тогда ваш Git запустит эквивалент git merge origin/master. - person torek; 16.04.2020
comment
Так, если, скажем, вы один feature/two, чьим восходящим потоком является origin/feature/two, git pull обновит origin/* и объединится с обновленным origin/feature/two, но git pull origin master обновит origin/master и объединится с обновленным origin/master. - person torek; 16.04.2020
comment
(См. Выше все предостережения о старых версиях Git, предшествующих 1.8.4 и т.п.) - person torek; 16.04.2020
comment
Потрясающий. Итак, подведем итог: git pull = git fetch + git merge origin/branch. Кроме того, git pull и git pull origin branch отличаются только тем, что последний обновляет только origin / branch, а не все origin / *, как это делает git pull. Если да, СПАСИБО #torek. Я надеюсь, что это поможет другим, как помогло мне. - person user33276346; 16.04.2020
comment
Да, хотя в кратком изложении не хватает множества хитрых ловушек, например, таких вещей, как древние версии Git, которые ведут себя по-другому. Git 1.7.x и 1.8.x (для различных значений x) все еще присутствуют в некоторых дистрибутивах, поэтому эти ловушки иногда важны. - person torek; 16.04.2020