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


355

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

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

git branch -D 3.2.*

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

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


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\..*'`

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\*`

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.*'`

Когда я пытаюсь это сделать, я получаю кучу сообщений об ошибках, таких как 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 'что-то' это совпадение с инверсией.


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

9

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

git branch -D `git branch --list 'at-*'`

Все ответы в основном говорят об этом, это просто оказывается самым простым.
tfantina

7

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


это позволяет только удалять локальные ветви
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() })


2

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

git branch | xargs git branch -d

git branch | xargs git branch -D

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


2

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

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

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


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 ".

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


0

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


0

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

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

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


0

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


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, почему бы вам просто не удалить идущие ветки, и тогда, если что-то пропущено, что не интересно в репозитории, автоматически соберется мусор, так что вы не будете надо беспокоить



-4

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

rm .git/refs/heads/3.2.*


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

Кроме того, это дает очень неожиданные результаты, если вы запускаете это в упакованном репозитории ( git gc). Не делай этого.
Матье Мой
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.