Включает ли "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 (первый квартал 2014 года), git fetch --tags извлекает теги в дополнение к тому, что выбирается той же командной строкой без опции.

Смотрите коммит c5a84e9 Майкла Хаггерти (mhagger):

Раньше "Фетч" --tags "опция считалась эквивалентной указанию refspec

refs/tags/*:refs/tags/*

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

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

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

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

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

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


Начиная с Git 2.5 (2 квартал 2015 года) git pull --tags является более надежным:

Смотрите коммит 19d122b Пола Тана ( pyokagan ), 13 мая 2015 г.
(Объединено Юнио С Хамано - gitster - в комитете cc77b99, 22 мая 2015 г.)

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

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

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


С Git 2.11+ (4 квартал 2016 года) git fetch быстрее

См. Коммит 5827a03 (13 октября 2016 г.) Джеффа Кинга ( peff )
(Объединено Юнио С Хамано - gitster - в коммите 9fcd144, 26 октября 2016 г.)

fetch: используйте "быстрый" has_sha1_file для тега следования

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

Этот патч учит 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. Вам нужно большое количество ссылок на теги на стороне сервера, которые являются кандидатами для автоматического следования (то есть, что у клиента нет). Каждый из них запускает перечитывание каталога пакета.
  3. При нормальных обстоятельствах клиент будет автоматически следовать этим тегам, и после одной большой выборки (2) больше не будет истинным.
    Но если эти теги указывают на историю, которая не связана с тем, что клиент извлекает иначе, то он никогда не будет автоматически следовать, и эти кандидаты будут влиять на нее при каждой выборке.

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

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

  • git fetch извлекает все заголовки веток (или все указанные в параметре конфигурации remote.fetch), все необходимые коммиты и все теги, которые доступны из этих веток. В большинстве случаев все теги достижимы таким образом.
  • git fetch --tags извлекает все теги, все необходимые для них коммиты. Он не будет обновлять заголовки веток, даже если они достижимы из выбранных тегов.

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

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

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

Я определил, что есть разница. "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/*
  • Перезаписывать локальные ветви и теги без ускоренной перемотки вперед + перед refspec
  • При необходимости перезаписать текущую проверенную ветку -u
  • Удалить ветки и теги, которых нет в удаленном -p
  • И заставить быть уверенным -f

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

В этом смысле, git fetch --tags ни в коем случае не является надмножеством git fetch, На самом деле все с точностью до наоборот.

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

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

git fetch upstream --tags

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

Другие вопросы по тегам