Чи можете ви видалити кілька гілок в одній команді за допомогою 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 видалить декілька гілок для вас одним викликом. На жаль, це не завершує назву філії. Хоча, в bash, ви можете:

git branch -D `git branch | grep -E '^3\.2\..*'`

2
Завершення 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
зіткнувся з

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
Це майже ідеальний метод для всіх, хто використовує стандартизовані позначення префіксу для імен гілок (наприклад, "виправити / ..." або "функція / ...").
Haz

4
Просто та ефективно! Я рекомендую хоч би запустити перший без | xargs git branch -dчастини, щоб перевірити, що насправді буде видалено.
mathielo

Рекомендується не 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

Редагувати:

Більш безпечна версія (запропонована Якубом Нарббським та Джефромі), оскільки вихід гілки гіта не передбачається використовувати в сценаріях:

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
gawi

1
Варто зауважити тим, хто не знає, що -Dє примусовим видаленням, слід використовувати -dв більшості випадків спочатку безпечніше.
redfox05

115

Ви можете використовувати гілку git --list, щоб перелічити відповідні гілки, а також використовувати гіт-гілку -D / -d для видалення відповідних гілок.

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

git branch -d `git branch --list '3.2.*'`

Коли я спробую це, я отримую купу повідомлень про помилки на кшталт error: branch 'package.json' not found.. Здається, що * розгорнуто занадто рано, і він намагається видалити гілку, що відповідає імені кожного файлу та каталогу.
Сурма

Це добре працює! У мене gitconfig
виникають

6
Ця відповідь повинна бути вищою у списку, супер чисто, працює, без
грепу

1
Приємно, що це легко перевірити спочатку, лише видавшиgit branch --list '3.2.*'
Буде

3
На вікнахgit branch -d (git branch --list '3.2.*').trim()
Маттіас Йозефссон

38

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

  1. Відкрийте термінал, або еквівалент.
  2. Введіть у гітці git | grep "pattern" для попереднього перегляду гілок, які будуть видалені.
  3. Введіть у гітці git | grep "візерунок" | xargs git гілка -D

Це рішення є приголомшливим, і якщо ви хочете повне пояснення кожної команди та як вона працює, її наведено тут .


28

Використовуйте

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

7
Невелика підказка полягає в тому, що якщо ви видалите останню частину команди "| xargs git branch -D", вона просто виведе відповідні гілки. Отже, ви можете переглянути гілки, які будуть видалені
Max MacLeod

1
Також я додав псевдонім, щоб спростити це: alias grefs='git for-each-ref --format="%(refname:short)"'тож я можу це зробитиgrefs | grep 'regexpattern' | xargs git branch -D
angularsen

Дуже сподобалося. Приємно і просто!
Bhargav Ponnapalli

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та використовувати пункт меню Відділення-> Видалити. Виберіть усі гілки, які ви хочете видалити, і дайте їм видобути.


це дозволяє лише видалити місцеві гілки
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 не знаходить файлів, але гілки були видалені.
Луріфаксель

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, ви можете скористатися поворотом для цього:

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

замініть feature/*будь-яким вподобаним малюнком.


6
grep - це не визнаний командлет для мене ... тому я змінив цю гітну гіт | де {$ _. Trim (). StartsWith ("помилка")} | % {git гілка -D $ _. Trim ()} і працювала!
Alex Alex


0

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


0

Я щойно прибрав великий набір застарілих локальних / віддалених відділень сьогодні.

Нижче, як я це зробив:

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

git гілка -a >> BranchNames.txt

2. додайте гілки, які я хочу видалити, до команди "git гілка -D -r":

git гілка -D -r походження / dirA / гілка01 походження / dirB / гілка02 походження / dirC / гілка03 (... додавання будь-яких назв гілок)

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

Якщо у вас були всі гілки для видалення в текстовому файлі (відгалуження до del.txt) (одна гілка на рядок), ви можете зробити це, щоб видалити всі такі гілки з віддаленого (походження): xargs -a branches-to-del.txt git push --delete origin


-1

Як у Git, всі гілки - це ніщо за посиланнями на git repo, чому б ти просто не видалив гілки, що збираються, .git/refа потім, якщо щось не буде цікаве у сховищі, буде автоматично зібрано сміття, щоб ти не став потрібно турбуватися.



-4

Ви можете видалити всі гілки, видаливши всі непотрібні переліки:

rm .git/refs/heads/3.2.*


2
Запропоновано з двох причин: 1. він використовує детальну інформацію про реалізацію (факт, що поточні версії Git зберігають гілки як файли у певному каталозі). Це може змінитися в майбутніх версіях, що зробить відповідь недійсною. 2. Не працює, якщо сховище знаходиться в окремому каталозі .
аксіак

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