Видаліть кілька віддалених гілок у git


128

У мене є член команди, який ненавмисно відтіснив понад 150 своїх місцевих відділень до нашого центрального репо. На щастя, всі вони мають однаковий префікс. Використовуючи цей префікс, чи є команда git або маленький крутий скрипт оболонки, який я можу використати, що видалить їх усі відразу?

Відповіді:


150

Використовуйте наступну команду для видалення всіх гілок з PREFIXпрефіксом на віддаленому сервері.

git branch -r | awk -F/ '/\/PREFIX/{print $2}' | xargs -I {} git push origin :{}

Ви можете спершу зробити сухий пробіг, щоб побачити, чи це гілки, які ви хочете видалити:

git branch -r | awk -F/ '/\/PREFIX/{print $2}'

2
Мені це подобається, тому що це один вкладиш, і я можу зробити перший пробіг. На жаль, воно помиляється з цим повідомленням: $ git branch -r | awk -F/ '/\/APR/{print $2}' | xargs -I {} git push origin :{} error: unable to push to unqualified destination: APR-04-DPH The destination refspec neither matches an existing ref on the remote nor begins with refs/, and we are unable to guess a prefix based on the source ref. error: failed to push some refs to 'GIT_URL'
Джейк А. Сміт

З git branch -r | awk -F/ '/\/APR/{print $2}', чи могли ви бачити перелічені всі назви філій APR у списку?
neevek

1
Гаразд, це тому, що APR-04-DPHгілку вже видалено. Погляньте на ці відповіді на запитання: це і це, і це . Відповіді на ці запитання стосуються тієї ж проблеми, можливо, ви захочете перевірити рішення самостійно.
neevek

26
якщо у вас є / у назвах вашої гілки (якщо ви використовуєте git-flow або щось подібне), друкуйте натомість {$ 2 "/" $ 3} замість цього
ajma

4
Я використовую msysgit в Windows, і наступна команда працювала для мене (спільно з коментарем @ ajma для імен гілок, що містять передні риски:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %
rikoe

96

Якщо вам подобається більш простий підхід, наприклад, видаліть 3 або 4 гілки:

git push origin --delete <branch1> <branch2> <branch3>

Важливо. Працює лише на Git v1.7.0 і вище.


6
Я закінчив використовуватиgit branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete
Арам Кочарян

36

Дякуємо Neevek за чудове та елегантне рішення!

Але у мене є проблеми з косою рисою в назвах гілок (я використовую Git Flow) через awkроздільник поля /( -Fопція)

Тож моє рішення засноване на Neevek's , але правильно аналізує назви гілок /. У цьому випадку я припускаю, що ваш дистанційний дзвонив origin. Команда для видалення віддалених гілок з іменами, на яких позначено PATTERN:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -I {} git push origin :{}

І не забудьте перевірити, що ви збираєтесь видалити:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}'

КОРИСНИЙ ПОРАДА: Якщо назви вашої гілки (без origin/префіксу) зберігаються у текстовому файлі (одна назва гілки на рядок), просто запустіть:

cat your_file.txt | xargs -I {} git push origin :{}

2
Використовуйте xargs -a file -Lзамість cat file | xargs. Ще простіше xargs -a file git push --delete origin.
musiKk

15

Це може бути дублююча відповідь, але нижче перевірена і працювала для мене чудово.

  1. Видаліть місцеву гілку насильно

git гілка -D гілка-назва

  1. Видалити віддалену гілку

git push origin - видалити ім'я гілки

  1. Видалити більше 1 місцевої гілки

git гілка -D гілка-ім’я1 гілка-ім’я2

  1. Видаліть більше 1 віддаленої гілки

git push origin - видалити гілку-ім'я1 гілку-ім’я2

  1. Видаліть локальну гілку з префіксом. Наприклад, наприклад /

git гілка -D $ (git гілка - список 'особливість / *')

git гілка -D backticks $ (гіт гілка - список 'особливість / *' backticks )

  1. Перерахуйте віддалену гілку з префіксом.

git гілка -r | grep -Eo 'особливість /.*'

  1. Видалити віддалену гілку з префіксом

git гілка -r | grep -Eo 'особливість /.*' | xargs -I {} походження git push: {}


2
Я думаю, ти мав намір уникнути
GPL

Як додати зворотній зв'язок?
Naren

1
@Naren: проблема полягає в тому, що форматування розмітки перетворює ваші спинки в команду стилізації. Я замінив їх іншим методом заміни команд (наприклад, "$ (command)" еквівалентний `command`, але не переводиться відміткою в щось дивне.) Інше, що ви могли зробити, - це уникнути задників за допомогою" \ "
Stabledog

13

Те саме з grep : git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}.

branch -rпоказує origin/prefix/branchname. Так знадобиться prefix/branchname.


Я думаю, ти мав на увазі xargs -I {} git push origin :{}, ні -i.
jojo

1
@jojo, AFAIK, оскільки -iвін використовує заміну за замовчуванням, {}але разом із -Iвами ви можете оголосити свою. ... щойно знайдені в посібнику:-i ... the same as -I{}
Кірбі

10

Рішення Neevek елегантне, але може бути і краще: рішення, як пропонується, називає один раз на гілку «git push», що означає додатковий обхід мережі за галуззю, який потрібно видалити. Оскільки ви все одно використовуєте awk, чому б не використовувати його для префіксу ':', а потім xargs може викликати «git push» рівно один раз та видалити всі гілки одразу:

Сухим запуском для переліку гілок, які буде видалено:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}'

Остаточне рішення фактично підштовхнути делетів:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin

2
Він прекрасно працює в ситуації, коли ви не можете використовувати опцію "-I" для xargs, коли у вас є нижча версія bash або використовується версія Windows git bash.
zchholmes

У мене було рішення xargs: replstr may not be emptyз Neevek, можливо, версія git .. git version 1.9.5Але це для мене чудово працювало. Дякую вам обом
IamFace

8

ресурс https://coderwall.com/p/eis0ba

    1 - List all your remote branches:

    $ git branch -r

    2 - Filter the branches by some regular expression. In this case I'm interested in deleting any branch with the 'feature-' prefix:

    $ git branch -r | awk -F/ '/\/feature-/{print $2}'
    3 - Pipe the last command to git push to delete them:
    # **Edit** - Removed extra colon, which is not needed
    $ git branch -r | awk -F/ '/\/feature-/{print $2}' | xargs -I {} git push origin {}
    4 - Grab a beer.

    5 - Remove any local reference to those branches:

    $ git remote prune origin

Дякую, це працювало для мене У такому випадку я міг би видалити кілька локальних гілок. Дякую!
Прашант Кабаде

5

Завдяки Стіву та Неєвеку я знайшов рішення, яке працювало для мене досить добре, я вважав, що варто поділитися:

Рішення Стіва працювало для мене з одним незначним регулюванням. Мої пульти були названі origin/feature/some-feature-nameтаким чином, я обрізав ваш awk:

git branch -r | awk -Forigin/ '/\/feature/ {print $2 $3}' | xargs -I {} git push origin :{}

Зараз це робить хороший невеликий потік видалення:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
To github.com:project/project-name.git
- [deleted]         feature/search-placeholder
To github.com:project/project-name.git
- [deleted]         feature/server-error-message
To github.com:project/project-name.git
- [deleted]         feature/six-point-asterisk

Мені було цікаво, чи є у когось ідеї для більш елегантного рішення, однак, це може дати щось подібне (мій сценарій CLI досить поганий, тому мені знадобиться деякий час, щоб це зрозуміти):

git push origin :feature/search-min-chars :feature/search-placeholder :feature/server-error-message :feature/six-point-asterisk

Це призведе до гарного одиничного виходу з одним мережевим запитом:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
- [deleted]         feature/search-placeholder
- [deleted]         feature/server-error-message
- [deleted]         feature/six-point-asterisk

4

Дякую Неєвеку. Це спрацювало добре після перенастроювання його для моєї мети:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}

Також мені потрібно було врахувати структуру папок. Мої гілки функцій містяться в структурі папок, таких як походження / особливість / PREFIX-FEATURENUMBER. Тому мені довелося створити свій шаблон із $ 2 = папка + $ 3 = назва гілки.


4

Усі використовують awk, не знаю чому. Я відчуваю, що це складніше. Ось що я використовую для видалення всіх віддалених гілок на моєму forkвіддаленому:

$ git branch -r --list 'fork/*' | sed 's/fork\///' | xargs git push --delete fork

Введіть grepміж xargsі sedякщо вам потрібно відфільтрувати список лише до підмножини віддалених гілок.


1
Дуже дякую. Цей фактично працював для мене серед усіх рішень .. grep повертав повну гілку з віддаленою назвою origin/blaprefix_anotherbla. Але при використанні sedвпорався з цим добре. Ще одна перевага цього підходу полягає в тому, що я використовую бітбукет і мені не потрібно вводити пароль автентифікації для кожного видалення гілки вручну. Це видаляє всі гілки в одній партії.
Мадхур Бхайя

Щоб видалити всі гілки git branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}
зеленого ґатунку

4

Я розумію, що це команда git, але якщо ви шукаєте альтернативне рішення, щоб зробити аналогічний чи такий же результат:

Ви можете зробити це звідси (Git Remove Remote Branches):

Потім виберіть потрібні гілки:

Переконайтеся, що у вас є дозволи на видалення віддалених гілок.


Це має бути головною відповіддю, це незалежно від платформи.
кармінгтон

Що таке програмне забезпечення та чи доступне воно для Linux?
abhisekp

1

У Github також є приємний інтерфейс користувача та механізм швидкого видалення гілок, це якщо ви скоріше використовувати інтерфейс


1
Так, це документально підтверджено тут , але ви все одно повинні натиснути один раз для кожної окремої гілки. Тут найголовніше рішення - це найкращий спосіб зробити багато гілок, для яких можна написати регулярний вираз.
thewoolleyman

0

Я намагався видалити всі віддалені гілки origin / release / r1-1 *, отже, наступний командний рядок добре працював.

git branch -r | awk -Forigin/ '/\/*r1-1/ {print $2}' |  xargs -I {} git push origin :{}

0

Мені не вдалося використати awk, оскільки ми використовуємо структуру косої риси для назви наших гілок.

git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i  sh -c 'git push origin --delete {}'

Отримайте всі віддалені відділення, отримайте лише одну для одного користувача, видаліть рядок "origin /" і виконайте видалення на кожній з них.


0

Сухий хід:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} echo {}

Видалення віддалених гілок:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Видалити лише повністю об'єднані віддалені гілки:

git branch -r --merged --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Пояснення:

sed "s/origin\///"видалить origin/з назви філії. Не знімаючи цього, я отримав:remote ref does not exist


0

Попередні відповіді допомогли мені видалити всі гілки випуску з 2018 року. Я запустив це у своєму командному рядку Windows 10. У мене встановлено клік , тому для мене працює Linux, як команди.

Сухий хід:

git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}

Якщо сухий пробіг показує гілки, які не мають віддаленого / походження. Виконайте нижче команду git prune, щоб виправити та перевірити ще раз.

git remote prune origin

Видаліть, як тільки ви будете задоволені результатом вище:

git branch -a | grep -o "release-.*2018" | xargs -I {} git push origin --delete {}

Якщо ви бачите: error: unable to delete 'release-...2018': remote ref does not exist. Потім запустіть попередню команду обрізки та спробуйте ще раз.


-4

Попередження: Це видалить усі віддалені гілки. Використовуйте обережно.

Я думаю, що мій спосіб видалення віддалених гілок є найкращим.

git branch -r | grep -v master | sed 's/origin\//:/'| xargs git push

Попередження: Це видалить усі віддалені гілки. Використовуйте обережно.


4
Прихильний як очевидний троль. Видалили б, якщо б у мене були права.
Джейк А. Сміт

де ти знайшов тролінг?
Дмитро Горпиненко

2
це не правильно, ви пропускаєте деякі життєво важливі аргументи для xargs, і це не відповідає на запитання.
Роб

@ JakeA.Smith Джейк, я думаю, ти думав, що цей код видалить віддалений майстер - що не так, оскільки grep -v master знайде все, крім master.
Вадим Самохін

@Rob що тут неправильно? Остаточний виконаний вислів буде таким, як git push: some_branch: another_branch, що абсолютно правильно.
Вадим Самохін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.