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

Хороший и простой вопрос - это функция "git fetch" строгий поднабор git fetch --tags?

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

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

Ответ 1

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

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

Ранее выборка "--tags" считалась эквивалентной указанию refspec

refs/tags/*:refs/tags/*

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

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

Если пользователь хочет получить только теги, то все еще возможно указать явный 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 (второй квартал 2015 года) git pull --tags стал более надежным:

См. коммит 19d122b от Пола Тана (pyokagan), 13 мая 2015 года.
(Merged by Junio C Hamano -- [TG410] -- in commit cc77b99, 22 May 2015)

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

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

It does not 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+ (Q4 2016) git fetch быстрее.

См. коммит 5827a03 (13 октября 2016 г.) от Джеффа Кинга (peff).
(Merged by Junio C Hamano -- [TG423] -- in commit 9fcd144, 26 Oct 2016)

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

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

Этот патч учит принуждению использовать 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 2.21 (февраль 2019), кажется, ввел регрессию, когда конфигурация remote.origin.fetch не является конфигурацией по умолчанию ('+refs/heads/*:refs/remotes/origin/*')

fatal: multiple updates for ref 'refs/tags/v1.0.0' not allowed

Git 2.24 (Q4 2019) добавляет еще одну оптимизацию.

См. коммит b7e2d8b (15 сентября 2019 г.) от Масая Сузуки (draftcode).
(Merged by Junio C Hamano -- [TG432] -- in commit 1d8b0df, 07 Oct 2019)

fetch: используйте oidset, чтобы сохранить нужные OID для быстрого поиска

Во время git fetch клиент проверяет, есть ли уже идентификаторы OID объявленных тегов в запросе на выборку, чтобы установить OID.
Эта проверка выполняется при линейном сканировании.
Для репозитория, имеющего много ссылок, повторение этого сканирования занимает 15+ минут.

Чтобы ускорить это, создайте oid_set для OID других рефери.

Ответ 2

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

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

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

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

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

Ответ 3

Я сам отвечу на это.

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

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

$ git fetch --tags
$ git fetch

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

Ответ 4

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

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

Ответ 5

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

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

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

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

Ответ 6

git fetch upstream --tags

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