Удалить несколько удаленных веток в 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}'
neevek
источник
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 и выше.

jfeston
источник
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: {}

Naren
источник
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.

Kirby
источник
Я думаю, вы имели в виду 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
andrewmart.in
источник
4

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

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

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

user3416278
источник
4

Все используют awk, не знаю почему. Я чувствую, что это более сложно. Вот что я использую для удаления всех удаленных веток на моем forkпульте дистанционного управления:

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

Добавьте grepмежду xargsи, sedесли вам нужно отфильтровать список только до подмножества удаленных ветвей.

void.pointer
источник
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 также имеет приятный пользовательский интерфейс и механизм для быстрого удаления веток, если вы предпочитаете использовать пользовательский интерфейс.

Alex
источник
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, что абсолютно правильно.
Вадим Самохин