git remote prune - не показывал столько обрезанных веток, сколько я ожидал

113

На странице руководства:

Deletes all stale tracking branches under <name>.
These stale branches have already been removed from the remote repository
referenced by <name>, but are still locally available in "remotes/<name>".

Итак, я удалил кучу веток, используя

git push origin :staleStuff

а затем побежал

git remote prune origin

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

Феликсиз
источник
7
чтобы узнать, какие ветки будут удалены, вы можете сделать git remote show originи поискать любые ветки, отмеченныеstale
Someone Somewhere

Ответы:

189

Когда вы используете git push origin :staleStuff, он автоматически удаляется origin/staleStuff, поэтому, когда вы запускали git remote prune origin, вы обрезали ветку, которая была удалена кем-то другим. Более вероятно, что вашим коллегам теперь нужно бежать, git pruneчтобы избавиться от веток, которые вы удалили.


Так что именно git remote prune? Основная идея: локальные ветки (не отслеживающие ветки) не затрагиваются git remote pruneкомандой и должны быть удалены вручную.

А теперь реальный пример для лучшего понимания:

У вас есть удаленный репозиторий с двумя ветками: masterи feature. Предположим, вы работаете над обеими ветками, поэтому в результате у вас есть эти ссылки в вашем локальном репозитории (полные имена ссылок даны, чтобы избежать путаницы):

  • refs/heads/master(короткое имя master)
  • refs/heads/feature(короткое имя feature)
  • refs/remotes/origin/master(короткое имя origin/master)
  • refs/remotes/origin/feature(короткое имя origin/feature)

А теперь типичный сценарий:

  1. Другой разработчик завершает всю работу над featureфайлом, объединяет его masterи удаляет featureветку из удаленного репозитория.
  2. По умолчанию, когда вы это делаете git fetch(или git pull), никакие ссылки не удаляются из вашего локального репозитория, поэтому у вас все еще есть все эти 4 ссылки.
  3. Вы решаете очистить их и бежать git remote prune origin.
  4. git обнаруживает, что эта featureветка больше не существует, поэтому refs/remotes/origin/featureэто устаревшая ветка, которую следует удалить.
  5. Теперь у вас есть 3 ссылки, в том числе refs/heads/feature, т.к. git remote pruneне удаляет ни однойrefs/heads/* ссылки.

По branch.<branch_name>.mergeпараметру конфигурации можно идентифицировать локальные ветви, связанные с удаленными ветвями отслеживания . Этот параметр на самом деле не требуется, чтобы что-то работало (возможно, кромеgit pull ), поэтому он может отсутствовать.

(обновлено примером и полезной информацией из комментариев)

Максимум
источник
Я понял ситуацию так: ветки все еще присутствуют локально, но удалены из удаленного репо. Теперь я хочу удалить все локальные ветки, которых нет на удаленном компьютере, поэтому я запускаю git prune. Вот что мне говорит «Эти устаревшие ветки уже удалены из удаленного репозитория». Я ошибся?
Felixyz 02
3
Вы правы, но, возможно, вы неправильно поняли значение слова «местные отделения» в случае git prune. Обрезке /refs/remotes/<remote_name>/подлежат только ветви ; никакие ветки в /refs/heads/не будут затронуты - вы должны управлять ими вручную.
max
Ага, я действительно так думал. Итак, у меня нет способа сделать то, что я хочу: автоматически удалить все ветки в головах, которые отслеживают удаленные ветки, проверяя, удалены ли эти удаленные ветки?
Felixyz
2
Для этого нет встроенной команды, но вы можете написать такой скрипт самостоятельно. Отслеживаемые ветки можно идентифицировать по наличию branch.<branch_name>.mergeпараметра конфигурации.
max
Этот ответ будет лучше, если вы добавите информацию в комментариях к самому ответу, чтобы всем, кто приходит сюда и имеет то же заблуждение, что и @Felixyz, не нужно было смешно смотреть на ваш ответ, а затем читать комментарии, чтобы наконец понять .
Акрикос,