Как сделать так, чтобы GIT локально соответствовал удаленному (как будто только что клонированный)?

Я удалил кучу веток BitBucket. Я хочу, чтобы мой локальный сервер отражал это без необходимости вручную удалять каждую ветку. Я должен быть в состоянии сделать что-то, чтобы «просто сделать так, чтобы мой локальный компьютер соответствовал моему удаленному, как если бы я только что сделал новый клон».

edit: я не хочу, чтобы какой-то скрипт из нескольких шагов выполнял grep и поиск, и я не хочу просто удалять свой проект и повторно клонировать - это должна быть простая функциональность, встроенная в GIT. На самом деле это всего лишь 8 ветвей, поэтому я мог бы сделать это вручную без особых усилий, но я пытаюсь изучить лучшие способы сделать это здесь.

edit2: один из связанных ответов предлагает:

git remote prune origin удаляет ветки отслеживания не на удаленном сервере.

Это похоже на то, что я хочу, но не удаляет локальные ветки. Он говорит, что удалено много исходных/ветвей, но git branch по-прежнему показывает все мои старые ветки, которые не существуют на удаленном компьютере.


person Art Vandelay    schedule 20.02.2019    source источник
comment
Возможно, вы захотите сделать новый клон.   -  person evolutionxbox    schedule 20.02.2019
comment
Почему свежий клон - это решение, которое вы исключили?   -  person RomainValeri    schedule 20.02.2019
comment
Это может помочь stackoverflow.com/questions/17983068/   -  person Hy L    schedule 20.02.2019
comment
Возможный дубликат Удалить ветки отслеживания, которые больше не удалены   -  person phd    schedule 20.02.2019
comment
stackoverflow.com/search?q=%5Bgit%5D+delete+local+branches   -  person phd    schedule 20.02.2019
comment
stackoverflow .com/questions/6373277/   -  person phd    schedule 20.02.2019
comment
stackoverflow.com/search?q=%5Bgit%5D+synchronize   -  person phd    schedule 20.02.2019
comment
Ваши ветки принадлежат вам. Git не удалит их без ваших прямых указаний. Вы не должны просто случайным образом удалять ветку foo, потому что origin/foo больше нет: например, у вас могут быть коммиты, которые нужно скопировать (выбрать вишенки) в какую-то другую ветку.   -  person torek    schedule 20.02.2019


Ответы (2)


TL;DR: вам действительно нужна настройка fetch.prune. Тем не менее, я отвечу на вопрос, который вы задали, а не на тот, который вы должны были задать. :-)

Чтобы превратить ваш существующий клон в то, что выглядит как свежий клон, вам нужно как минимум четыре шага.

  1. Выполнить git fetch -p. Или настройте fetch.prune на true в локальном репозитории или в настройках для каждого пользователя и запустите git fetch. Это удалит все origin/* имена для удаленного отслеживания в вашем репозитории, соответствующие именам ветвей, которые раньше существовали, но больше не существуют в репозитории по адресу origin.

  2. Вручную удалите все ветки, которые вам не нужны — все, кроме одной. Для этого вам нужно проверить тот, который вы хотите сохранить. Автоматизируйте это удаление, если хотите, но имейте в виду, что если у вас есть коммиты, которые вы никогда не отправляли вверх по течению, вы можете потерять эти коммиты на этом этапе. Увидеть ниже.

  3. git reset --hard ваши оставшиеся ветки своим удаленным аналогам. На этом этапе вы можете потерять некоторые коммиты. Увидеть ниже.

  4. Выполнить git clean -dfx. Увидеть ниже.

Теперь у вас есть то, что напоминает свежий клон, за исключением следующих элементов:

  • В журнале ссылок для вашего HEAD по-прежнему хранятся все ваши недавние действия, в которых могут сохраняться некоторые коммиты. Вы также можете очистить это, используя git reflog expire --expire=all --expire-unreachable=all.

  • Любые тайники, которые у вас есть, все еще существуют. Вы можете удалить их все с помощью git stash clear.

  • Любые необычные ссылки, которые вы сделали, все еще существуют (например, refs/notes/, refs/replace/ из git replace). Вы должны удалить их вручную, если хотите.

  • Любой статус поверхностного клонирования сохраняется. Вы можете использовать git fetch --unshallow, чтобы очистить это.

  • Некоторые биты «предполагать неизмененные» или «пропустить рабочее дерево» все еще могут быть установлены в индексе. Вы можете использовать git update-index --no-assume-unchanged и git update-index --no-skip-worktree, чтобы исправить это. Вам нужно сделать это только в том случае, если вы установили эти биты ранее; Git никогда не устанавливает их самостоятельно.

(Я думаю, что это все, но я могу пропустить один или два пункта.)

Примечания

Если бы вам нужно было сделать новое git clone, вы бы:

  • создайте новый пустой репозиторий: mkdir name; cd name; git init
  • добавьте к нему удаленное имя origin, используя соответствующий URL-адрес: git remote add origin url
  • запустите git fetch, чтобы получить все существующие ветки в качестве имен удаленного отслеживания origin/*
  • выберите одну из этих ветвей (на основе вашего аргумента -b для git clone) для создания локально
  • запустите git checkout name, который создаст имя из origin/name.

Этот новый репозиторий имеет те же имена для удаленного отслеживания, которые остались после шага 1 (удаление выборки), поэтому шаг 1 исправляет ваши имена для удаленного отслеживания. У него нет имен ветвей — нет ссылок refs/heads/* — кроме тех, которые были созданы на последнем шаге, поэтому на шаге 2 они удаляются. Вы, конечно, находитесь в этой оставшейся ветке, поэтому шаг 2 включает git checkout name, а шаг 3, git reset --hard, заставляет имя вашей ветки указывать на правильный коммит при обновлении всего вашего индекса и большей части вашего рабочего дерева.

Конечно, неотслеживаемые файлы и каталоги могут остаться, поэтому на шаге 4, git clean -dfx, Git удалит их, включая файлы, игнорируемые директивами .gitignore.

Чтобы автоматизировать удаление веток, которые не являются текущей веткой, вам понадобится небольшой скрипт. В связанных вопросах есть некоторые (возможные дубликаты). Но они удаляют ваши ветки, которые не являются ничьими ветками. Вы не должны просто удалять их случайным образом: вы должны уже удалить их самостоятельно, когда закончите с ними, чтобы нечего было удалять. Вот почему шаги 2 и 3 перечислены, но их не следует выполнять — по крайней мере, не автоматически.

Последняя операция, git clean -dfx, удаляет артефакты сборки (например, скомпилированные файлы *.o или файлы Python с байтовым кодом *.pyc). Обычно вы хотите сделать это вручную под своим контролем, а не только потому, что что-то изменилось выше по течению.

person torek    schedule 20.02.2019
comment
Я просмотрел вашу настройку fetch.prune = true, но это тоже не работает. Я сделал git config remote.origin.prune true, затем git fetch, но сохранил свои локальные ветки. Мой ЖКТ сломан или я что-то упустил? - person Art Vandelay; 20.02.2019
comment
Предположим, вы работали над новой функцией и создали локальную ветку feature. Вы отправили в источник, так что теперь у вас также есть origin/feature. Кто-то приходит и думает, что вы закончили, и удаляет feature из источника. Вы запускаете git fetch -p, и ваш origin/feature уходит. Но ты сейчас работаешь над feature. Должен ли ваш Git удалить вашу ветку feature? - person torek; 20.02.2019
comment
Это именно то, что я хочу. Наш рабочий процесс заключается в том, что мы разветвляем основное репо, создаем ветки из ветки разработки и создаем запросы на извлечение из этих веток в ветку разработки основного репо. Никто никогда не удалит мою удаленную ветку, потому что я единственный, кто работает в этой ветке. - person Art Vandelay; 20.02.2019
comment
В этом случае вы захотите удалить как локально, так и удаленно по ходу дела. Вы можете создать псевдоним для этого: [alias] del2 = !f() { git branch -d $1; git push origin --delete $1; } f например. Теперь вам нужна одноразовая очистка. git branch не удаляет несколько ветвей, поэтому в bash-ish for b in branch1 branch2 branch3; do git branch -D $b; done. - person torek; 20.02.2019

Я видел много хороших предложений, но похоже, что реальный ответ заключается в том, что GIT не предоставляет более простой команды, чем удаление проекта и использование клона GIT. IMO должна быть команда git reset --hard для всех веток и всего остального, что отслеживает GIT.

person Art Vandelay    schedule 21.02.2019