Удалить несколько удаленных веток в git


129

У меня есть член команды, который непреднамеренно переместил более 150 своих местных филиалов в наше центральное репо. К счастью, все они имеют одинаковый префикс. Можно ли использовать этот префикс с помощью команды git или классного небольшого сценария оболочки, который удалит все их сразу?

Ответы:


151

Используйте следующую команду, чтобы удалить все ветки с 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}
аджма

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

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 , но правильно анализирует имена веток с помощью /. В этом случае я предполагаю, что ваш пульт позвонил 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 branch -D имя-ветки

  1. Удалить удаленную ветку

git push origin --delete имя-ветки

  1. Удалить более 1 локального филиала

git branch -D имя-ветки1 имя-ветки2

  1. Удалить более 1 удаленной ветки

git push origin --delete имя-ветки1 имя-ветки2

  1. Удалить локальную ветку с префиксом. Например, функция / *

git branch -D $ (git branch --list 'особенность / *')

git branch -D обратные кавычки $ (git branch --list 'feature / *' backticks )

  1. Перечислить удаленную ветку с префиксом.

git branch -r | grep -Eo 'особенность /.*'

  1. Удалить удаленную ветку с префиксом

git branch -r | grep -Eo 'feature /.*' | xargs -I {} git push origin: {}


2
я думаю, вы хотели избежать обратных
GPL

Как добавить обратные кавычки?
Naren

1
@Naren: проблема в том, что форматирование уценки превращает ваши обратные кавычки в команду стилизации. Я заменил их другим методом подстановки команд (например, «$ (command)» эквивалентно `command`, но не преобразуется с помощью markdown во что-то странное.) Еще вы могли бы избежать обратных кавычек с помощью '\'
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 или используется git bash версии для Windows.
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

Спасибо Neevek. Это хорошо сработало после перенастройки его для моей цели:

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

Мне также нужно было учитывать структуру папок. Мои ветки функций находятся в такой структуре папок, как origin / feature / 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 {}
greenkeeper

4

Я понимаю, что это для команды git, но если вы ищете альтернативное решение для получения аналогичного или такого же результата:

Вы можете сделать это отсюда (Git Remove Remote Branch):

Затем выберите нужные ветки:

Убедитесь, что у вас есть разрешения на удаление удаленных веток.


Это должен быть главный ответ, он не зависит от платформы.
Кармингтон

Какое программное обеспечение и доступно ли оно для 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. Я установил clink , так что команды типа 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. Затем запустите предыдущую команду prune и попробуйте еще раз.


-4

Предупреждение: это удалит все удаленные ветки. Используйте с осторожностью.

Я думаю, что мой способ удаления удаленных веток - лучший.

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

Предупреждение: это удалит все удаленные ветки. Используйте с осторожностью.


4
Проголосовали за явного тролля. Удалил бы, если бы у меня были права.
Джейк А. Смит

где ты нашел троллинг?
Дмитрий Горпыненко 06

2
это неверно, вам не хватает некоторых важных аргументов в пользу xargs, и он не отвечает на вопрос.
Роб

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

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