Включает ли “git fetch --tags” в себя ”git fetch"?
Вопрос
Хороший и простой вопрос - является ли функция "git fetch" строгим подмножеством git fetch --tags
?
Тоесть.если я сбегу git fetch --tags
, есть ли когда - нибудь причина для немедленного запуска git fetch
сразу после этого?
О чем git pull
и git pull --tags
?Та же ситуация?
Решение
Примечание:начиная с git 1.9/ 2.0 (1 квартал 2014), git fetch --tags
извлекает теги в дополнение к которые извлекаются из той же командной строки без указанной опции.
Видишь фиксация c5a84e9 Автор: Майкл Хаггерти (mhagger):
Ранее fetch's "
--tags
" опция была сочтена эквивалентной указанию refspecrefs/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 (2 квартал 2015) git pull --tags
является более надежным:
Видишь фиксация 19d122b Автор: Пол Тан (pyokagan
), 13 мая 2015 года.
(Объединено Джунио Си Хамано -- 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
:извлекать теги в дополнение к другие материалы, 2013-10-30, Git 1.9.0+),git fetch --tags
будет извлекать теги в дополнение к любым настроенным ссылочным спецификациям.
Следовательно, если возникает какая-либо ситуация отсутствия кандидатов на слияние, то это не потому, что--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%
Это применимо только к ситуации, когда:
- Вам нужно создать множество пакетов на стороне клиента
reprepare_packed_git()
дорого (самая дорогая часть - это поиск дубликатов в несортированном списке, который в настоящее время является квадратичным).- Вам нужно большое количество ссылок на теги на стороне сервера, которые являются кандидатами для автоматического следования (т. Е. которых нет у клиента).Каждый из них запускает повторное чтение каталога пакета.
- При нормальных обстоятельствах клиент автоматически отслеживал бы эти теги, и после одной большой выборки (2) больше не было бы true.
Но если эти теги указывают на историю, которая не связана с тем, что клиент извлекает в противном случае, то она никогда не будет автоматически отслеживаться, и эти кандидаты будут влиять на нее при каждой выборке.
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 версии v1.8 и старше.
Большая часть этого была сказана в других ответах и комментариях, но вот краткое объяснение:
git fetch
извлекает все заголовки ветвей (или все, указанные параметром remote.fetch config), все необходимые для них коммиты и все теги, которые доступны из этих ветвей.В большинстве случаев таким образом доступны все теги.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/*"
И если вы хотите сделать это по умолчанию для этого репозитория, вы можете добавить вторую спецификацию к выборке по умолчанию:
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
В большинстве ситуаций, 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
работает просто отлично, он получит только новые теги и не получит никакой другой кодовой базы.