В git, как мне синхронизировать мои теги с удаленным сервером?
Есть ли способ сохранить мои локальные теги git в одном месте с тегами пульта? То есть - не только получать новые теги при создании (как обычно, когда fetch
-ную /pull
-ing), но также удаляет теги больше не на пульте, а также удаляет существующие теги, когда кто-то еще git push -f
тег. я знаю что могу git fetch remotename
с последующим git remote prune remotename
добиться аналогичного поведения для филиалов.
7 ответов
... также удаляйте теги больше не на пульте
git fetch
получает с Git 2.17 (Q2 2018) удобный способ избавиться от устаревших тегов, которые хранятся локально.
См. Коммит 6317972, коммит 97716d2, коммит e249ce0, коммит 627a129, коммит d0e0747, коммит 2c72ed7, коммит e1790f9, коммит 59caf52, коммит 82f34e0, коммит 6fb23f5, коммит ca3065e, коммит bf16ab7, коммит eca142d, коммит ce3ab3, комманду 750d0da aa59e0e (09 февраля 2018 г.) автор Арварфьорд Бьярмасон ( avar
)
(Объединено Юнио С Хамано - gitster
- в комитете c1a7902 от 06 марта 2018 года)
получить: добавить
--prune-tags
вариант иfetch.pruneTags
конфигДобавить
--prune-tags
возможностьgit-fetch
, вместе сfetch.pruneTags
опция конфигурации и-P
стенография (-p
является--prune
).
Это позволяет выполнять любое из:git fetch -p -P git fetch --prune --prune-tags git fetch -p -P origin git fetch --prune --prune-tags origin
Или просто:
git config fetch.prune true && git config fetch.pruneTags true && git fetch
Вместо гораздо более многословного:
git fetch --prune origin 'refs/tags/*:refs/tags/*' '+refs/heads/*:refs/remotes/origin/*'
До этой функции было больно поддерживать сценарий извлечения из репозитория, в котором регулярно удаляются как его ветви, так и теги, и иметь наши локальные ссылки для отражения в восходящем направлении.
На работе мы создаем теги развертывания в репозитории для каждого выпуска, и их много, поэтому они архивируются в течение нескольких недель по соображениям производительности.
Без этого изменения трудно централизованно настроить такие репозитории в
/etc/gitconfig
(на серверах, которые используются только для работы с ними). Вам нужно установитьfetch.prune=true
глобально, а затем для каждого репо:git -C {} config --replace-all remote.origin.fetch "refs/tags/*:refs/tags/*" "^\+*refs/tags/\*:refs/tags/\*$"
Теперь я могу просто установить
fetch.pruneTags=true
в/etc/gitconfig
а так и пользователи бегаютgit pull
"автоматически получит семантику обрезки, которую я хочу.
Небольшое исследование показало, что git не может определить разницу между локальными и внешними тегами (все теги идут в.git/refs/tags/). Следовательно, невозможно определить разницу между локально созданными тегами и удаленными тегами, которые могут быть удалены. Затем параметры сводятся к следующему: наличие постоянно растущего набора тегов или только тегов, находящихся на сервере.
git push --tags origin && \
git tag | xargs -n1 git tag -d && \
git fetch --tags
Оставьте первую строку для последнего поведения и, возможно, используйте git alias'd для частого использования.
Альтернативой может быть создание ветви (так как они могут быть идентифицированы как локальные / удаленные) в точке тега и никогда не записываться в нее снова. Тогда использование remotename / branchname в качестве тега для оформления заказа будет синхронизировать теги (в дополнение к git fetch
а также git remote prune remotename
).
В любом случае это взлом, и "правильный" ответ - перестать постоянно менять теги.
Другое решение, которое на самом деле работает для меня:
git tag -l | xargs git tag -d && git fetch -t
Используйте эту команду для синхронизации тегов (удалите все локальные, затем выберите все удаленные)
git tag -d $(git tag) # delete all local tags
git fetch --all # fetch all remote to local
git push --tags отправит ваши локальные теги на сервер. По умолчанию git fetch (первая половина git pull или git pull --rebase) будет извлекать теги, но вы можете указать -t или --tags, чтобы извлечь все из них.
Я не уверен, как удалить удаленно удаленные теги, но выборка должна сбрасывать любые принудительно обновляемые теги.
Отказ от ответственности это использует внутренние механизмы git (некоторые могут утверждать, что файловая система является интерфейсом git, но это для другого дня:D)
# Blow away all local tags, this will remove any that are tagged locally
# but are not on the remote
rm .git/refs/tags/*
# Download all the tags from the remote
git fetch --tags
Вот альтернативное решение:
git fetch -p +refs/tags/*:refs/tags/*
Из git fetch doc:
-p --prune
Перед извлечением удалите все ссылки на удаленное отслеживание, которые больше не существуют на пульте. Теги не подлежат сокращению, если они выбираются только из-за автоматического следования тега по умолчанию или из-за опции --tags. Однако, если теги выбираются из-за явного refspec (либо в командной строке, либо в удаленной конфигурации, например, если пульт был клонирован с параметром --mirror), то они также подлежат сокращению.