Можете ли вы удалить несколько веток в одной команде с помощью Git?

355

Я хотел бы, чтобы очистить свой локальный репозиторий, который имеет кучу старых ветвей: например 3.2, 3.2.1, 3.2.2и т.д.

Я надеялся на хитрый способ убрать их сразу. Поскольку они в основном следуют соглашению о точечном выпуске, я подумал, что, возможно, есть ярлык, чтобы сказать:

git branch -D 3.2.*

и убить все ветви 3.2.x.

Я попробовал эту команду, и она, конечно, не сработала.

Doug
источник
11
git branch -D $(git branch | grep 3.2*)- это сработало для меня. Удаляет ветки, название которых начинается с «3.2». grep- сопоставление с образцом на выходе ( git branchв данном случае). $()- означает выполнить и разместить результат. |- цепочки.
Эдуард
4
Стоит отметить, что для тех, кто не знает, что -Dтакое принудительное удаление, следует использовать -dв большинстве случаев в первую очередь безопаснее.
redfox05

Ответы:

363

Не с этим синтаксисом. Но вы можете сделать это так:

git branch -D 3.2 3.2.1 3.2.2

По сути, git branch удалит несколько веток за вас одним вызовом. К сожалению, это не делает завершение имени ветви. Хотя в bash вы можете сделать:

git branch -D `git branch | grep -E '^3\.2\..*'`
slebetman
источник
3
Завершение на git branch -D/-dработе отлично работает для меня. Возможно, вы захотите обновить свой (возможно, из самой последней директории git.git contrib).
Каскабель
19
Вместо того, чтобы git branch | ...вы могли использовать $(git for-each-ref --format='%(refname:short)' refs/heads/3.*). Я знаю, что он длиннее, но гарантированно будет подходящим выводом, но в то же время git branchбудет хорош с такими вещами, как *и ->(для symrefs), которые могут запутать вас в скриптах / однострочниках.
Каскабель
3
Может быть, я единственный, кто столкнулся с этой проблемой, но я grepвсегда включал флаг --color=always- git branch -Dбросал, error: branch 'my_branch' not found.пока не побежал без цветного флага.
eebbesen
@eebbesen Вы отключили это глобально? Я сталкиваюсь с той же проблемой при запускеgit branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
qmmr
2
С расширением брекет вы могли бы написать , git branch -D 3.2{,.1,.2}чтобы удалить все три ветви gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck
147

Ну, в худшем случае, вы можете использовать:

git branch | grep '3\.2' | xargs git branch -d
Карл Норум
источник
22
Это в значительной степени идеальный метод для тех, кто использует стандартизированную префиксную нотацию для имен веток (например, «fix / ...» или «feature / ...»).
Хаз
4
Просто и эффективно! Я бы порекомендовал запустить сначала без | xargs git branch -dчасти, чтобы проверить, что на самом деле будет удалено.
Матьело
Рекомендуется не grepвыводить git branch, так как он предназначен для чтения, а не для разбора. Может измениться в любое время. используйте for-each-refвместе с --formatпараметрами, как предлагается в других ответах, а затем объедините с предложениями в этом ответе.
redfox05
138
git branch  | cut -c3- | egrep "^3.2" | xargs git branch -D
  ^                ^                ^         ^ 
  |                |                |         |--- create arguments
  |                |                |              from standard input
  |                |                |
  |                |                |---your regexp 
  |                |
  |                |--- skip asterisk 
  |--- list all 
       local
       branches

РЕДАКТИРОВАТЬ:

Более безопасная версия (предложенная Jakub Narębski и Jefromi), так как вывод ветки git не предназначен для использования в скриптах:

git for-each-ref --format="%(refname:short)" refs/heads/3.2\* | xargs git branch -D

... или без xargs:

git branch -D `git for-each-ref --format="%(refname:short)" refs/heads/3.2\*`
gawi
источник
14
Не используйте git branchвывод для сценариев. Использование git for-each-ref.
Якуб Наребски
1
Чтобы удалить теги с символом @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt
Имеет опечатку. Должно быть "/3.2/*", а не "/3.2*". Также, кажется, вы скопировали и вставили другие ответы в свои.
Макс МакЛауд
Здесь нет опечатки. Со страницы If one or more patterns are given, only refs are shown that match against at least one pattern, either using fnmatch(3) or literally, in the latter case matching completely or from the beginning up to a slash
руководства
1
Стоит отметить, что для тех, кто не знает, что -Dтакое принудительное удаление, следует использовать -dв большинстве случаев в первую очередь безопаснее.
redfox05
115

Вы можете использовать git branch --list, чтобы вывести список подходящих веток, и использовать git branch -D / -d, чтобы удалить подходящие ветки.

Один пример лайнера:

git branch -d `git branch --list '3.2.*'`
50shadesofbae
источник
Когда я пытаюсь это сделать, я получаю кучу сообщений об ошибках, таких как error: branch 'package.json' not found.. Кажется, что * раскрывается слишком рано, и он пытается удалить ветку, соответствующую имени каждого файла и каталога.
Сурьма
Это хорошо работает! У меня проблемы с использованием этого в качестве псевдонима, gitconfigхотя ...
whomaniac
6
Этот ответ должен быть выше в списке, супер чистый, работает, не grep
jemiloii
1
Приятно, что этот тест легко проверить первым, git branch --list '3.2.*'
Will
3
На окнахgit branch -d (git branch --list '3.2.*').trim()
Маттиас
38

Недавно я искал решение той же проблемы, наконец, я нашел один ответ, и он работает очень хорошо:

  1. Откройте терминал или эквивалентный.
  2. Наберите в git ветке | grep "pattern" для предварительного просмотра ветвей, которые будут удалены.
  3. Наберите в git ветке | grep "шаблон" | xargs git branch -D

Это отличное решение, и если вы хотите получить полное объяснение каждой команды и того, как она работает, оно дано здесь .

КДж Гор
источник
28

использование

git for-each-ref --format='%(refname:short)' 'refs/heads/3.2.*' |
   xargs git branch -D
Якуб Наребски
источник
7
Небольшой совет: если вы удалите последнюю часть команды "| xargs git branch -D", она просто выведет соответствующие ветки. Таким образом, вы можете просмотреть ветки, которые будут удалены
Макс Маклеод
1
Также я добавил псевдоним, чтобы упростить это: alias grefs='git for-each-ref --format="%(refname:short)"'чтобы я мог сделатьgrefs | grep 'regexpattern' | xargs git branch -D
angularsen
Любил это. Красиво и просто!
Бхаргав Поннапалли
15

Может быть, вы найдете это полезным:

Если вы хотите удалить все ветви, которые не являются, например, «master», «foo» и «bar»

git branch -D `git branch | grep -vE 'master|foo|bar'`

grep -v 'что-то' это совпадение с инверсией.

Adi
источник
Мне лично нравится -Dвариант сравнить с другим ответом. Спасибо за ответ здесь @Adi. Решения работает для меня.
AMIC MING
9

Я поставил свои инициалы и тире (at-) в качестве первых трех символов имени ветви по этой точной причине:

git branch -D `git branch --list 'at-*'`
Алан Твиди
источник
Все ответы в основном говорят об этом, это просто оказывается самым простым.
tfantina
7

Если вы не ограничены использованием командной строки git, то вы всегда можете запустить git guiи использовать пункт меню Branch-> Delete. Выберите все ветви, которые вы хотите удалить, и дайте ему разорваться.

Efpophis
источник
это позволяет только удалять локальные ветви
Stealth Rabbi
7

Решение Powershell:

Если вы используете Windows, вы можете использовать PowerShell для удаления нескольких веток одновременно ...

git branch -D ((git branch | Select-String -Pattern '^\s*3\.2\..*') | foreach{$_.ToString().Trim()})
//this will remove all branches starting with 3.2.

git branch -D ((git branch | Select-String -Pattern 'feature-*') | foreach{$_.ToString().Trim()})
// this will delete all branches that contains the word "feature-" as a substring.

Вы также можете точно настроить, как должно работать сопоставление с образцом, используя команду Select-String от Powershell. Посмотрите на документы PowerShell .

Имтиаз Шакил Сиддик
источник
6

Держите "развиваться" и удалять все остальные в локальном

    git branch | grep -v "develop" | xargs git branch -D 
Даниил
источник
5

Я сделал небольшую функцию, которая может быть полезна, основываясь на ответе @gawi (выше).

removeBranchesWithPrefix() {
  git for-each-ref --format="%(refname:short)" refs/heads/$1\* | xargs git branch -d
}

Добавьте это к своему .bash_profileи перезапустите свой терминал. Затем вы можете позвонить из командной строки следующим образом:

removeBranchesWithPrefix somePrefix

Запись

В настоящее время он настроен на мягкое удаление, что означает, что он не будет удалять ветви, если они не были объединены. Если вам нравится жить на грани, измените -dна -Dи он все удалит с префиксом независимо от!

логан
источник
5

Если вам действительно нужно почистить все свои ветки, попробуйте

git branch -d $(git branch)

Он удалит все ваши локальные объединенные филиалы, кроме той, которую вы сейчас регистрируете.

Это хороший способ сделать ваш район чистым

Юлин
источник
Это работало достаточно хорошо для меня. Он оставил две ветви, кроме той, которая была мной, и которую я затем удалил с помощью той же команды, но с использованием заглавной буквы «-D» вместо «-d». Я получил несколько ошибок о том, что git не находит файлы, но ветви были удалены.
Lurifaxel
3

Вам может понравиться этот маленький элемент ... Он тянет список и запрашивает подтверждение каждого элемента, прежде чем окончательно удалить все выбранные элементы ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "remove branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done`

Используйте -D для принудительного удаления (как обычно).

Для удобства чтения, вот что разбито построчно ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* |
    while read -r line; do 
        read -p "remove branch: $line (y/N)?" answer </dev/tty;
        case "$answer" in y|Y) echo "$line";; 
        esac; 
    done`

вот подход XARGS ...

git for-each-ref --format="%(refname:short)" refs/heads/\* |
while read -r line; do 
    read -p "remove branch: $line (y/N)?" answer </dev/tty;
    case "$answer" in 
        y|Y) echo "$line";; 
    esac; 
done | xargs git branch -D

наконец, мне нравится иметь это в моем .bashrc

alias gitselect='git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "select branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done'

Таким образом, я могу просто сказать,

gitSelect | xargs git branch -D.
Хаос Крафтер
источник
3

Для чистых душ, которые используют PowerShell, здесь небольшой скрипт git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })

CodeVision
источник
2

у меня работает правильно

git branch | xargs git branch -d

git branch | xargs git branch -D

удалить все локальные филиалы

velastiqui
источник
2

Используйте следующую команду, чтобы удалить все ветви (извлеченные ветви не будут удалены).

git branch | cut -d '*' -f 1 | tr -d " \t\r" | xargs git branch -d

Изменить: я использую Mac Os

ILYAS_Kerbal
источник
0

Если вы находитесь на Windows, вы можете использовать PowerShell для этого:

 git branch | grep 'feature/*' |% { git branch -D $_.trim() }

замените feature/*любой шаблон, который вам нравится.

Мо Валипур
источник
6
grep для меня не распознанный командлет ... поэтому я изменил эту ветку git | где {$ _. Trim (). StartsWith ("ошибка")} | % {git branch -D $ _. Trim ()} и сработало!
Алекс
0

Вы можете использовать git guiдля удаления нескольких веток одновременно. Из командной строки / Bash -> git gui-> Удаленный -> Удалить ветку ... -> выберите удаленные ветви, которые вы хотите удалить -> Удалить.

Терри Чыонг
источник
0

Я только что убрал большой набор устаревших локальных / удаленных филиалов сегодня.

Вот как я это сделал:

1. перечислите все имена ветвей в текстовый файл:

git branch -a >> BranchNames.txt

2. добавьте ветви, которые я хочу удалить, к команде "git branch -D -r":

git branch -D -r origin / dirA / branch01 origin / dirB / branch02 origin / dirC / branch03 (... добавлять любые имена ветвей)

3. выполнить cmd

И этот работает намного быстрее и надежнее, чем " git push origin --delete ".

Это может быть не самый умный способ, как указано в других ответах, но этот довольно простой и простой в использовании.

RainCast
источник
0

Если вы установили Git GUI, который является надстройкой по умолчанию для Windows, то он самый простой. Вы можете использовать Ctrl, чтобы выбрать несколько веток и удалить их одним щелчком мыши.

peiz
источник
0

Если вы используете оболочку Fish, вы можете использовать stringфункции :

git branch -d (git branch -l "<your pattern>" | string trim)

Это не сильно отличается от параметров Powershell в некоторых других ответах.

mdiin
источник
0

Если у вас есть все ветви, которые нужно удалить в текстовом файле (branch-to-del.txt) (по одной ветви на строку), вы можете сделать это, чтобы удалить все такие ветви с удаленного компьютера (origin): xargs -a branches-to-del.txt git push --delete origin

code4kix
источник
0

Чтобы удалить несколько веток на основе указанного шаблона, сделайте следующее:

Откройте терминал или его эквивалент и введите следующие команды:

git branch | grep "<pattern>" (preview of the branches based on pattern)

git branch | grep "<pattern>" | xargs git branch -D (replace the <pattern> with a regular expression to match your branch names)

Удалите все ветки 3.2.x, которые вам нужно набрать

git branch | grep "3.2" | xargs git branch -D

Это все!

Вы хороши, чтобы пойти!

Анкит Джиндал
источник
-1

Так как в Git все ветки являются ничем по ссылкам .git/refна репозиторий git, почему бы вам просто не удалить идущие ветки, и тогда, если что-то пропущено, что не интересно в репозитории, автоматически соберется мусор, так что вы не будете надо беспокоить

Debajit
источник
-4

Вы можете удалить все ветви, удалив все ненужные ссылки:

rm .git/refs/heads/3.2.*

Артур Овчарек
источник
2
Понижено по двум причинам: 1. он использует детали реализации (тот факт, что текущие версии Git хранят ветви как файлы в определенной директории). Это может измениться в будущих версиях, сделав ответ недействительным. 2. Не работает, если хранилище находится в отдельном каталоге .
Axiac
Кроме того, это дает очень неожиданные результаты, если вы запускаете это в упакованном репозитории ( git gc). Не делай этого.
Матье Мой