Я думал, что git fetch --prune origin <refspec> делает следующее
а) удалить устаревшие ветки удаленного отслеживания
б) затем выполните загрузку, как это делает git fetch origin <refpec>.
но читая док,
git fetch --prune origin refs/tags/*:refs/tags/* не ведет себя так, как указано выше.
Итак, поведение при обрезке зависит от refspec.
Как будет вести себя обрезка с помощью fetch в отношении переданного refspec? Я использую git 2,18
Обновлено: добавление дополнительных наблюдений, которые я видел:
Мой remote.origin.fetch = remote.origin.fetch=refs/heads/*:refs/remotes/origin/*
Почему я об этом говорю? Из-за этого странного отношения
Дело 1 :git fetch --prune --dry-run origin
Это удаляет ветки удаленного отслеживания, отсутствующие в удаленном репозитории. Потом скачивает вроде git fetch --dry-run origin
Случай 2:git fetch --prune --dry-run origin refs/heads/*:refs/remotes/origin/*
Это первый удаляет все мои ветки удаленного отслеживания (обратите внимание, что jk нуждался в сокращении и не создается повторно), а затем создает их снова, а затем обновляет их. Странный !! Вот пример:
- [deleted] (none) -> origin/holo
- [deleted] (none) -> origin/ioio
- [deleted] (none) -> origin/jj
- [deleted] (none) -> origin/jkkk
- [deleted] (none) -> origin/jk
* [new branch] holo -> holo
* [new branch] ioio -> ioio
* [new branch] jj -> jj
* [new branch] jk -> jkkk
= [up to date] holo -> origin/holo
= [up to date] ioio -> origin/ioio
= [up to date] jj -> origin/jj
= [up to date] jkkk -> origin/jkkk
Случай 3:git fetch --prune --dry-run origin master или git fetch --prune --dry-run origin master:master
Ничего не обрезает (мастер существовал и в удаленном репо, но в моем локальном были ветки удаленного отслеживания, которые требовали обрезки, но он не касался его). После этого ведет себя как git fetch --dry-run origin master
* branch master -> FETCH_HEAD
= [up to date] master -> origin/master
Случай 4:git fetch --prune --dry-run origin refs/tags/*:refs/tags/*
Это сначала просто обрезает теги, а затем ведет себя как git fetch --dry-run origin refs/tags/*:refs/tags/*
Случай 5:git fetch origin --prune --verbose --dry-run master:refs/remotes/origin/kk
(Предполагая, что ветка kk больше не существует в удаленном репо)
Это сначала удаляет refs/remotes/origin/kk, а затем воссоздает его и обновляет.
- [deleted] (none) -> origin/kk
= [up to date] master -> origin/kk
= [up to date] master -> origin/master
Итак, случаи 1 и 4 - это то, что, как я думал, должно вести себя так, как объяснялось в начале моего вопроса. Варианты 2, 3 и 5 не соответствовали шаблону. Итак, что я должен сделать в таком случае? Как будет вести себя обрезка с помощью fetch в отношении переданного refspec? Есть ли какая-то общая закономерность среди всех, с помощью которой мы можем объяснить поведение?
Если вы хотите просто подумать о проблеме (а затем поработать над самим Git и / или отправить исправления людям из Git), основная проблема здесь в том, что в протоколе передачи v0 мы начинаем с выполнения git ls-remote и получения все ссылок из другой Git, который включает возможность сокращения: мы можем видеть, как все их ссылки будут отображаться в наших ссылках. Остальное - это просто вопрос программирования. Однако новый протокол передачи v2 намеренно избегает получает все ссылки из другого Git, что вообще повлияет на нашу способность выполнять --prune.





Я не пробовал это делать и в любом случае не рекомендую делать это широко (в разных версиях Git были разные реализации кода
--pruneс разными угловыми ошибками), но похоже, что опция--refmapповлияет на работу--prune, поэтому вы мог бы попробовать это.