Включает ли "git fetch --tags" "git fetch"?

хороший и простой вопрос-Является ли функция "git fetch" строгим подмножеством git fetch --tags?

т. е. если я сбегу git fetch --tags, есть ли когда-нибудь причина немедленно запустить git fetch сразу после этого?

насчет git pull и git pull --tags? Та же ситуация?

6 ответов


Примечание: начиная с git 1.9 / 2.0 (Q1 2014), git fetch --tags извлекает теги кроме что извлекается той же командной строкой без опции.

посмотреть совершить c5a84e9 by Майкл Хаггерти (mhagger):

ранее, проныре "--tags" вариант считался эквивалентным указанию refspec

refs/tags/*:refs/tags/*

в командной строке; в частности, это вызвало the remote.<name>.refspec конфигурация игнорируется.

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

если пользователь хочет получить только теги, тогда еще можно указать явный refspec:

git fetch <remote> 'refs/tags/*:refs/tags/*'

обратите внимание, что документация до 1.8.0.3 была неоднозначной в отношении этого аспекта "fetch --tags" поведение.
зафиксировать f0cb2f1 (2012-12-14)fetch --tags сделал документацию соответствующей старому поведению.
Эта фиксация изменяет документацию в соответствии с новым поведением (см. Documentation/fetch-options.txt).

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


С Git 2.5 (Q2 2015)git pull --tags более надежен:

посмотреть совершить 19d122b by Поль Тан (pyokagan), 13 мая 2015 года.
(слитый Junio C Hamano -- gitster -- на совершить cc77b99, 22 мая 2015)

pull: удалить --tags ошибка в случае без слияния кандидатов

С 441ed41 ("git pull --tags": ошибка с лучшим сообщением., 2007-12-28, Git 1.5.4+),git pull --tags будет печатать сообщение об ошибке, если git-fetch не вернули никаких кандидатов на слияние:

It doesn't make sense to pull all tags; you probably meant:
       git fetch --tags

это потому, что в это время git-fetch --tags отменяет любые настроен refspecs, и, следовательно, не было бы объединения кандидатов. Таким образом, сообщение об ошибке было введено во избежание путаницы.

С c5a84e9 (fetch --tags: fetch tags кроме прочее, 2013-10-30, Git 1.9.0+),git fetch --tags будет получать теги в дополнение для любых настроенных refspecs.
Следовательно, если какая-либо ситуация слияния кандидатов не происходит, это не потому, что --tags был установлен. Таким образом, это специальное сообщение об ошибке теперь не имеет значения.

чтобы избежать путаницы, удалите это сообщение об ошибке.


С Git 2.11+ (Q4 2016) git fetch быстрее.

посмотреть совершить 5827a03 (13 окт 2016) by Джефф Кинг (peff).
(слитый Junio C Hamano -- gitster -- на совершить 9fcd144, 26 октября 2016)

fetch: используйте "quick"has_sha1_file по тегу following

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

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

вот результаты из включенного сценария perf, который устанавливает ситуацию, аналогичную описанной выше:

Test            HEAD^               HEAD
----------------------------------------------------------
5550.4: fetch   11.21(10.42+0.78)   0.08(0.04+0.02) -99.3%

это относится только к ситуации где:

  1. у вас есть много пакетов на стороне клиента, чтобы сделать reprepare_packed_git() дорого (самая дорогая часть-поиск дубликатов в несортированном списке, который в настоящее время квадратичен).
  2. вам нужно большое количество ссылок тегов на стороне сервера, которые являются кандидатами для автоматического следования (т. е. у клиента нет). Каждый из них запускает повторное чтение каталога pack.
  3. в нормальных обстоятельствах, клиент автоматически следуйте этим тегам и после одной большой выборки (2) больше не будет истинным.
    Но если эти теги указывают на историю, которая отключена от того, что клиент в противном случае извлекает, то он никогда не будет автоматически следовать, и эти кандидаты повлияют на каждую выборку.

Примечание: этот ответ действителен только для git v1.8 и старше.

большинство из этого уже было сказано в других ответах и комментариях, но вот краткое объяснение:

  • git fetch извлекает все головки ветвей (или все, указанные пультом ДУ.fetch config option), все необходимые для них коммиты и все теги, которые доступны из этих ветвей. В большинстве случаев все теги доступны таким образом.
  • git fetch --tags извлекает все теги, все совершает необходимые для них. Это будет не обновить головки ветвей, даже если они доступны из тегов, которые были извлечены.

Summary: если вы действительно хотите быть полностью в курсе, используя только fetch, вы должны сделать оба.

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


Я собираюсь ответить на это сам.

Я определил, что есть разница. "git fetch --tags" может принести все теги, но он не приносит никаких новых коммитов!

оказывается, нужно сделать это, чтобы быть полностью "в курсе", т. е. реплицировать "git pull" без слияния:

$ git fetch --tags
$ git fetch

Это позор, потому что это в два раза медленнее. Если бы только "git fetch" имел возможность делать то, что он обычно делает и все метить.


общая проблема здесь в том, что git fetch получать +refs/heads/*:refs/remotes/$remote/*. Если какой-либо из этих коммитов имеет теги, эти теги также будут извлечены. Однако, если есть теги, недоступные для любой ветви на удаленном, они не будут извлечены.

на --tags опция переключает refspec на +refs/tags/*:refs/tags/*. Вы мог бы задать git fetch схватить обоих. Я почти уверен, что просто сделаю git fetch && git fetch -t вы бы использовали следующую команду:

git fetch origin "+refs/heads/*:refs/remotes/origin/*" "+refs/tags/*:refs/tags/*"

и если вы хотите сделать это по умолчанию для этого РЕПО, вы можете добавить второй refspec для выборки по умолчанию:

git config --local --add remote.origin.fetch "+refs/tags/*:refs/tags/*"

это добавит второй fetch = строка .git/config для этого пульт.


я некоторое время искал способ справиться с этим для проекта. Вот что я придумал.

git fetch -fup origin "+refs/*:refs/*"

в моем случае я хотел, чтобы эти функции

  • захватить все главы и теги пульт, чтобы использовать refspec refs/*:refs/*
  • переписать локальные ветви и теги с non-fast-forward + перед refspec
  • при необходимости перезаписать выделенную ветку -u
  • удалить ветви и теги, отсутствующие в remote -p
  • и сила, чтобы быть уверенным -f

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

в этом смысле git fetch --tags никоим образом не является надмножеством git fetch. На самом деле все как раз наоборот.

git pull, конечно, это не что иное, как обертка для git fetch <thisrefspec>; git merge. Рекомендуется привыкайте делать вручную git fetchи git mergeing, прежде чем сделать прыжок в git pull просто потому, что это поможет вам понять, что git pull делает в первую очередь.

это, как говорится, отношения точно такие же, как с git fetch. git pull - это надмножество git pull --tags.


git fetch upstream --tags

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