Як я можу видалити всі гілки Git, які були об'єднані?


1934

У мене є багато гіт Git. Як видалити гілки, які вже об'єднані? Чи є простий спосіб видалити їх усіх, а не видаляти їх по одному?


46
Щоб бути трохи більш конкретним, git branch -Dвидаляється будь-яка гілка, будь то об'єднана чи ні.
PhilT

12
Ви також можете це зробити безпосередньо з GitHub, якщо ви перейдете до розділу "гілки" вашого репо (наприклад, github.com/<username>/<repo_name>/branches ). Там має бути список усіх ваших гілок, з червоним значком кошика на боці, який видалить вибрану гілку. Набагато швидше, ніж робити це в терміналі! Також покаже, наскільки далеко вперед / позаду masterкожної гілки. Однак ваш місцевий клієнт все ще перелічить старі відділення, якщо ви працюєте git branch -a; використовувати git fetch --pruneдля їх видалення (відповідно до цієї відповіді ).
користувач5359531

3
Сценарій , щоб зробити це локально або віддалено - з перевірками безпеки і попередньо сконфігуровані «безпечні гілки»: github.com/fatso83/dotfiles/tree/master/utils / ... git delete-merged --doit origin абоgit delete-merged --doit --local
oligofren

Ви також можете використовувати цю програму для автоматичного видалення об'єднаних гілок.
Себас ван Боксель

rm -fr work && git clone http://example.com/work.gitз роками став найпростішим способом вийти з соління з кисіль.
Реакційний

Відповіді:


3114

ОНОВЛЕННЯ:

Ви можете додати інші гілки, щоб виключити, наприклад, master і dev, якщо ваш робочий процес має такі можливі предки. Зазвичай я відгалужую тег "спринт-старт" і майстер, dev і qa - не предки.

По-перше, перерахуйте всі гілки, які були об’єднані у віддалений.

git branch --merged

Можливо, ви побачите кілька гілок, які не хочете видаляти. ми можемо додати декілька аргументів, щоб пропустити важливі гілки, які ми не хочемо видаляти, як master чи arate. Наступна команда буде пропускати головну гілку і все, що має в ній розробник.

git branch --merged| egrep -v "(^\*|master|dev)"

Якщо ви хочете пропустити, ви можете додати його до команди egrep, як описано нижче. Гілка skip_branch_nameне буде видалена.

git branch --merged| egrep -v "(^\*|master|dev|skip_branch_name)"

Щоб видалити всі локальні гілки, які вже об'єднані в поточну перевірену гілку:

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

Ви можете бачити, що майстер і дев виключаються на випадок, якщо вони є предком.


Ви можете видалити об'єднану локальну гілку за допомогою:

git branch -d branchname

Якщо це не об'єднано, використовуйте:

git branch -D branchname

Щоб видалити його з віддаленого використання:

git push --delete origin branchname

git push origin :branchname    # for really old git

Після того як ви видалите гілку з віддаленого, ви можете обрізати, щоб позбутися відгалужених гілок відстеження за допомогою:

git remote prune origin

або обрізати окремі гілки віддаленого відстеження, як підказує інша відповідь:

git branch -dr branchname

Сподіваюсь, це допомагає.


46
Попередження: Якщо ви тільки що створили гілку, вона також видалить її. Переконайтеся, що у списку немає новоствореної гілки, перш ніж запустити команду верхньої вершини.
Гері Харан

153
ПРОПОЗИЦІЯ ПОПЕРЕДЖЕННЯ: reflog врятує ваш бекон. Тому не хвилюйтесь.
Адам Дімітрук

33
Майте на увазі, що перша команда видаляє лише локальні гілки, тому це не так "небезпечно", як деякі вказували.
ifightcrime

79
Варіант PowerShell, щоб я міг знайти його тут наступного разу, коли я git branch --merged | %{$_.trim()} | ?{$_ -notmatch 'develop' -and $_ -notmatch 'master'} | %{git branch -d $_}
гуглив

23
Це створює помилку, fatal: branch name requiredякщо у вас немає гілок, які слід видалити. Щоб уникнути того, що ви можете перейти, -rщоб xargsвін не запускався, git branch -dякщо stdin порожній. (Це розширення xargs GNU, відповідно до сторінки man).
Маріус Гедмінас

456

Щоб видалити всі гілки на віддалених, які вже об’єднані:

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

В останніх версіях Git

git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin

ОНОВЛЕННЯ (від @oliver; оскільки не вміщується в коментарях, але вже достатньо відповідей) : якщо ви перебуваєте у відділенні ABC, то ABC з’явиться у результатах, git branch -r --mergedоскільки галузь не вказана, тому гілка за замовчуванням на поточну гілку та гілку завжди кваліфікується як злита з самим собою (тому що немає відмінностей між гілкою і самою собою!).

Тож або вкажіть галузь:

git branch -r --merged master | grep -v master ...

АБО перший майстер оформлення замовлення:

git checkout master | git branch -r --merged | grep -v ...

18
Найкраща відповідь на сьогоднішній день. Лише зауважте, названа моя головна гілка, devтому мені довелося це змінити
Доріан

41
Мені довелося додати | grep originпісля того, grep -v masterщоб запобігти натисканню гілок інших віддалених на походження. Настійно рекомендую попередньо перевірити вихід, використовуючиgit branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo
L0LN1NJ4

9
Я трохи змінився, щоб виключити також developгалузь. git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin. Тепер це виявилося моїм псевдонімом.
сарат

8
Що зробив це найкращою відповіддю, яку я прочитав, - це -rаргумент, якого я не бачив ніде більше. Зрозуміло, що лише місцеві відділення варті того, щоб займатися господарством. Але дистанційні також повні сміття.
Asbjørn Ulsberg

19
Обережно - щойно зрозумів: це, очевидно, знайде гілки, об'єднані з поточною гілкою , а не майстер, тому якщо ви на myFeatureBranchній, витріть origin/myFeatureBranch. Напевно, найкраще git checkout masterспочатку.
jakub.g

190

Просто трохи продовживши відповідь Адама:

Додайте це до конфігурації Git, запустивши git config -e --global

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d"

І тоді ви можете видалити всі локальні об'єднані гілки, виконуючи простий git cleanup.


11
чи не повинна бути перша команда: git branch --merged masterоскільки ви хочете переглянути те, що було об'єднано в головний, а не перевірену в даний час гілку?
Джо Філіпс

@JoePhilllips Деякі люди мають головну гілку не майстер, але замість цього developабо, devі в такому випадку команда не вдасться fatal: malformed object name, краще мати загальну команду, і ви несете відповідальність за її виконання
дивно

1
@JoePhilllips Суть цієї відповіді полягає в тому, щоб зібрати відповідь Адама (головна відповідь на це запитання) у корисному псевдонімі git. Відповідь Адама не має того, що ви пропонуєте, і так багато людей вважають це корисним, тому я схильний не міняти свого. Я рекомендую відкрити дискусію щодо відповіді Адама, якщо ви сильно ставитесь до цього
real_ate

13
Додавання -rдо xargsзапобігає непотрібним помилкам ( branch name required) при запуску цього псевдоніма кілька разів або коли не залишається гілки для видалення. Мій псевдонім виглядає приблизно так:cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d"
spezifanta

1
Поточна команда не фільтрує майстра та розробляє гілки
Андрій Ф.

83

Це також працює для видалення всіх об'єднаних гілок, крім головного.

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d

3
Тепер він не видалить жодну гілку, що міститься masterв ній. Спробуйте grep -v ^master$для середини.
wchargin

Я також дозволю, | grep -v '^\*'щоб уникнути видалення поточної гілки, якщо ви не на майстер
svassr

5
Це чудово, дякую! Одне застереження для тих, хто використовує це: зауважте, що в ньому є два пробіли grep -v '^ master$'. Якщо ви введете його і пропустите його, ви видалите, masterякщо не будете на ньому.
стигер

3
@ Mr.Polywhirl ваше редагування порушує команду, і вам слід повернути її. Два пробіли необхідні, оскільки git branchбуде перераховано кожну назву гілки в новому рядку з двома пробілами зліва, якщо це не перевірена в даний час гілка. Ви по суті гарантували, що кожен, хто виконує цю команду, видалить свою головну гілку, якщо це не перевірена в даний час гілка.
стигер

79

Ви хочете виключити master& developгілки з цих команд.

Місцевий git ясний:

git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d

Віддалений git clear:

git branch -r --merged | grep -v '\*\|master\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin

Синхронізувати локальний реєстр віддалених відділень:

git fetch -p

3
+1 також для віддаленої версії (але менш потрібна, оскільки у нас віддалений --prune). Також варто відзначити, що тозо не працюватиме зі старшою версією git
malko

4
git config --global --add fetch.prune trueпідрізати автоматично на витяг або витягнути.
T3rm1

1
Зверніть увагу, чорнослив - це не те саме, що віддалений ясний. Віддалене очищення фактично видаляє віддалені гілки, які повністю об'єднані з вашою поточною гілкою. Prune очищає лише ваш локальний реєстр віддалених гілок, які вже видалені.
Гвідо Буман

Слово повністю трохи вводить в оману, оскільки гілка буде вважатися об'єднаною, коли вона була об'єднана раніше, але має нові коміти після об'єднання, які не були об'єднані.
scones

Щоб видалити всі git branch -r --merged | grep -v '\*\|master\|develop' | grep '^\s*origin/' | sed 's/origin\///' | tr "\n" " " | xargs git push --delete origin
віддалені

48

Для тих із вас, хто перебуває у Windows та віддають перевагу сценаріям PowerShell, ось такий, який видаляє локальні об'єднані гілки:

function Remove-MergedBranches
{
  git branch --merged |
    ForEach-Object { $_.Trim() } |
    Where-Object {$_ -NotMatch "^\*"} |
    Where-Object {-not ( $_ -Like "*master" )} |
    ForEach-Object { git branch -d $_ }
}

13
З цікавості це можна скоротити до git branch --merged | ?{-not ($_ -like "*master")} | %{git branch -d $_.trim()}
Ієна Баллард

5
@IainBallard Звичайно, я міг використовувати псевдоніми. Це не рекомендується, коли ви хочете досягти максимальної читабельності. github.com/darkoperator/PSStyleGuide/blob/master/English.md
Klas Mellbourn

1
впевнений. Я вважаю вашу відповідь дуже корисною :-) Однак іноді синтаксис силових оболонок довгої форми перешкоджає тому, що відбувається в блоках. Але насамперед, я висував щось, що ви можете скопіювати / вставити або набрати як разове. Знову дякую.
Ієн Баллард

4
Ось for /f "usebackq" %B in (``git branch --merged^|findstr /v /c:"* " /c:"master"``) do @git branch -d %Bоднолінійний шматок для cmd-оболонки Windows, який зберігає майстер та поточну гілку: (зітхніть, замініть подвійні зворотні котирування одинарними, я не впевнений, як відформатувати літерал, що містить зворотні котирування)
yoyo

42

Я вже багато років використовую відповідь Адама. Однак, є деякі випадки, коли вона не вела себе так, як я очікувала:

  1. гілки, які містили слово "майстер", були ігноровані, наприклад, "notmaster" або "masterful", а не тільки головна гілка
  2. гілки, що містили слово "dev", були ігноровані, наприклад, "dev-test", а не лише гілка dev
  3. видалення гілок, доступних від HEAD поточної гілки (тобто не обов'язково головного)
  4. у відірваному стані HEAD, видаляючи кожну гілку, доступну з поточної комісії

1 та 2 були зрозумілі для вирішення, лише змінивши регулярний вираз. 3 залежить від контексту того, що ви хочете (тобто видаляйте лише гілки, які не були об'єднані в головний чи проти вашої поточної гілки). 4 може стати катастрофічним (хоча і підлягає відшкодуванню git reflog), якщо ви ненавмисно запустили це у відірваному стані HEAD.

Нарешті, я хотів, щоб це все було в одноланковому вкладиші, який не потребував окремого сценарію (Bash | Ruby | Python).

TL; DR

Створіть псевдонім git "sweep", який приймає необов'язковий -fпрапор:

git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'

і викликати його за допомогою:

git sweep

або:

git sweep -f

Довга детальна відповідь

Мені було найпростіше створити приклад git repo з деякими гілками та зобов’язується перевірити правильність поведінки:

Створіть нове git repo за допомогою одного коміту

mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"

Створіть кілька нових гілок

git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
  bar
  develop
  foo
* master
  masterful
  notmaster

Бажана поведінка: виберіть усі об'єднані гілки, крім: майстер, розробляти чи поточно

Оригінальний регулярний вираз не вистачає гілок "майстерно" та "немайстра":

git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
  bar

З оновленим регулярним виразом (який зараз виключає "розвивати", а не "dev"):

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster

Перейдіть на гілку foo, зробіть нову фіксацію, а потім перевірте нову гілку, foobar, на основі foo:

echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"

Моя поточна гілка є foobar, і якщо я повторно запускаю вищевказану команду для переліку гілок, які я хочу видалити, гілка "foo" включається, навіть якщо вона не була об'єднана в головний:

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  foo
  masterful
  notmaster

Однак якщо я запускаю одну і ту ж команду на master, гілка "foo" не включається:

git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

І це просто тому, що git branch --mergedза замовчуванням до HEAD поточної гілки, якщо не вказано інше. Принаймні для мого робочого процесу я не хочу видаляти локальні гілки, якщо вони не були об'єднані в основний, тому я віддаю перевагу наступному варіанту:

git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

Стан окремої головки

Опираючись на поведінку за замовчуванням, git branch --mergedмає ще більш значні наслідки у відстороненому стані HEAD:

git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  foo
  foobar
  masterful
  notmaster

Це видалило б гілку, на якій я щойно був, "foobar" разом з "foo", що майже напевно не є бажаним результатом. Однак з нашим переглянутою командою:

git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

Один рядок, включаючи власне видалення

git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d

Всі загорнуті в git псевдонім "sweep":

git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'

Псевдонім приймає необов’язковий -fпрапор. Типовою поведінкою є видалення лише гілок, які були об'єднані в головний, але -fпрапор видалить гілки, які були об'єднані в поточну гілку.

git sweep
Deleted branch bar (was 9a56952).
Deleted branch masterful (was 9a56952).
Deleted branch notmaster (was 9a56952).
git sweep -f
Deleted branch foo (was 2cea1ab).

Для чого потрібно створити функцію? Чи не git configатомний?
ВасиліНовіков

Для того, щоб мати справу з ТІнструкція -f 'аргумент (якщо я правильно розумію ваше запитання)
завихрення

1
але як це допомагає? Я маю в виду початок вирази, !f(){ git branch .... Це оголошення функції, правда? Чому б не почати безпосередньо git branch ...?
ВасиліНовіков

1
Ви абсолютно праві. Відповідно відредагував мою відповідь. Дякуємо за вказівник!
Вихори

Чи не зробить таке, що не так, як режим без сили? git checkout master && git branch -d `git branch --merged` && git checkout - За винятком того, що це видалить develop, але це може бути більш простий підхід.
Гвідо


18

Використання Git версії 2.5.0:

git branch -d `git branch --merged`

16
Це може видалити masterгілку btw!
Wazery

4
Правда. Я використовую його лише тоді, коли впевнений, що ввімкнувся master.
drautb

11
git branch -d $(git branch --merged | grep -v master)
алекс

1
Це небезпечно, якщо у вас є потік, уявіть, що у вас є головний <- етап <- dev. Все-таки найпростіше рішення imo
Джозеф Бріггс

14

Ви можете додати фіксацію до опції --merger. Таким чином ви можете переконатись лише в тому, щоб видалити гілки, об'єднані в тобто початкове / головне

Наступна команда видалить об'єднані гілки з вашого походження.

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 

Ви можете перевірити, які гілки будуть видалені замінюючи походження git push --delete з відлунням

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo

2
Мені подобається тестовий варіант
iwein

12

Я використовую наступний сценарій Ruby, щоб видалити свої вже об'єднані локальні та віддалені гілки. Якщо я роблю це для сховища з декількома віддаленими пристроями і хочу лише видалити з одного, я просто додаю оператор select у список віддалених, щоб отримати лише потрібні віддалені файли.

#!/usr/bin/env ruby

current_branch = `git symbolic-ref --short HEAD`.chomp
if current_branch != "master"
  if $?.exitstatus == 0
    puts "WARNING: You are on branch #{current_branch}, NOT master."
  else
    puts "WARNING: You are not on a branch"
  end
  puts
end

puts "Fetching merged branches..."
remote_branches= `git branch -r --merged`.
  split("\n").
  map(&:strip).
  reject {|b| b =~ /\/(#{current_branch}|master)/}

local_branches= `git branch --merged`.
  gsub(/^\* /, '').
  split("\n").
  map(&:strip).
  reject {|b| b =~ /(#{current_branch}|master)/}

if remote_branches.empty? && local_branches.empty?
  puts "No existing branches have been merged into #{current_branch}."
else
  puts "This will remove the following branches:"
  puts remote_branches.join("\n")
  puts local_branches.join("\n")
  puts "Proceed?"
  if gets =~ /^y/i
    remote_branches.each do |b|
      remote, branch = b.split(/\//)
      `git push #{remote} :#{branch}`
    end

    # Remove local branches
    `git branch -d #{local_branches.join(' ')}`
  else
    puts "No branches removed."
  end
end

Майте на увазі, якщо я вкраду цей ласощі для невеликої бібліотеки помічників git? github.com/yupiq/git-branch-util
logan

1
Іди до цього, я б не ставлю це сюди, якби я піклувався про те, щоб люди якось повторно використовували код
mmrobins

@mmrobins У вас є додатковий \/на початку заяви про відхилення для remote_branchesрядка. Це помилка друку чи це служить цілі?
Jawwad

@mmrobins, о, неважливо, я бачу b.split(/\//)лінію зараз
Jawwad

Якщо ви хочете зробити це в основному, але через ванільний баш, а не рубін: stackoverflow.com/a/37999948/430128
Раман

11

Як видалити об'єднані гілки в консолі PowerShell

git branch --merged | %{git branch -d $_.Trim()}

Якщо ви хочете виключити основні або будь-які інші імена гілок, ви можете передавати програму PowerShell Select-String таким чином і передавати результат git branch -d:

git branch -d $(git branch --merged | Select-String -NotMatch "master" | %{$_.ToString().Trim()})

1
Вищі відповіді пропонують фільтрувати майстер або інші гілки. Для тих, хто хоче це зробити в powerhell: git branch --merged | findstr / v "майстер" | % {git branch -d $ _. trim ()}
tredzko

@tredzko Хороший момент. FTR, вища відповідь - stackoverflow.com/questions/6127328/… - ви можете перепублікувати свій коментар із цим посиланням, і я потім
видаляю

він також намагається видалити * master:)
iesen

9

відповідь kuboon пропустив видалення гілок, які мають ім'я слова master у назві гілки. Наступне покращує його відповідь:

git branch -r --merged | grep -v "origin/master$" | sed 's/\s*origin\///' | xargs -n 1 git push --delete origin

Звичайно, це не видаляє саму гілку "майстра" :)


8

У Git немає команди, яка зробить це автоматично для вас. Але ви можете написати сценарій, який використовує команди Git, щоб дати вам те, що вам потрібно. Це можна зробити багатьма способами залежно від того, яку модель розгалуження ви використовуєте.

Якщо вам потрібно знати, чи була гілка об'єднана в master, наступна команда не дасть результату, якщо myTopicBranch був об'єднаний (тобто ви можете її видалити)

$ git rev-list master | grep $(git rev-parse myTopicBranch)

Ви можете використовувати команду гілки Git і проаналізувати всі гілки в Bash і зробити forцикл для всіх гілок. У цьому циклі ви перевірте команду вище, чи можете ви видалити гілку чи ні.



7

Примітка : я не задоволений попередніми відповідями (не працюю над усіма системами, не працюю на віддаленому, не вказуючи - занурену гілку, не фільтрую точно). Отже, я додаю власну відповідь.

Є два основні випадки:

Місцеві

Ви хочете видалити локальні гілки , які вже об'єднані з іншою локальною гілкою . Під час видалення ви хочете зберегти деякі важливі галузі, наприклад, майстер, розвиватися тощо.

git branch --format "%(refname:short)" --merged master | grep -E -v '^master$|^feature/develop$' | xargs -n 1 git branch -d

Примітки :

  • git branch output --format ".." - це знімати пробіли та допускати точну відповідність грепу
  • grep -Eвикористовується замість egrep , тому він працює також у системах без egrep (тобто: git для windows).
  • grep -E -v '^master$|^feature/develop$' це вказати локальні гілки, які я не хочу видаляти
  • xargs -n 1 git branch -d: виконайте видалення локальних гілок (для віддалених не буде)
  • звичайно, ви отримуєте помилку, якщо ви спробуєте видалити гілку, яка наразі перевірена. Тож пропоную заздалегідь перейти до майстра.

Віддалений

Ви хочете видалити віддалені гілки , які вже об'єднані з іншою віддаленою гілкою . Під час видалення потрібно зберегти деякі важливі гілки, наприклад HEAD, master, релізи тощо.

git branch -r --format "%(refname:short)" --merged origin/master | grep -E -v '^*HEAD$|^*/master$|^*release' | cut -d/ -f2- | xargs -n 1 git push --delete origin

Примітки :

  • для віддаленого ми використовуємо -rопцію та надаємо повну назву відділення :origin/master
  • grep -E -v '^*HEAD$|^*/master$|^*release' це відповідати віддаленим гілкам, які ми не хочемо видаляти.
  • cut -d/ -f2-: видаліть непотрібний префікс 'origin /', який інакше друкується git branchкомандою.
  • xargs -n 1 git push --delete origin : виконати видалення віддалених гілок.

7

Якщо у вас є Windows, ви можете використовувати Windows Powershell або Powershell 7 з Out-GridView, щоб мати гарний список гілок і мишкою вибрати, яку саме потрібно видалити:

git branch --format "%(refname:short)" --merged  | Out-GridView -PassThru | % { git branch -d $_ }

введіть тут опис зображення після натискання кнопки "ОК" Powershell передасть імена цих гілок в git branch -dкоманду та видалить їх введіть тут опис зображення


6

Ви можете використовувати git-del-br інструмент .

git-del-br -a

Ви можете встановити його за pipдопомогою

pip install git-del-br

PS: Я автор інструменту. Будь-які пропозиції / відгуки вітаються.


1
@ stackoverflow.com/users/100297/martijn-pieters : Чому цю відповідь було видалено та знято з оскарження?
tusharmakkar08

1
Ваша відповідь та інструмент не працюють. Я витрачаю на це пару годин. Нічого.
SpoiledTechie.com

@ SpoiledTechie.com: Чи можете ви сказати мені, з якою проблемою ви стикаєтесь саме? Я користуюся ним регулярно.
tusharmakkar08

Я можу поділитися скріншотом, якщо ви хочете зробити це в автономному режимі? spoiledtechie на цій пошті в Google. :)
SpoiledTechie.com

5

Якщо ви хочете видалити всі локальні гілки, які вже об'єднані у гілку, на якій ви зараз перебуваєте, я створив безпечну команду для цього, грунтуючись на попередніх відповідях:

git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d

Ця команда не вплине на вашу поточну гілку чи головну гілку. Він також розповість вам, що він робить, перш ніж це зробити, використовуючи -t прапор xargs.



5

Я використовую схему іменування git-flow esque, тому для мене це дуже безпечно:

git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d

В основному він шукає об'єднані комісії, які починаються з рядка fix/або feature/.


4

Спробуйте виконати таку команду:

git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

Використовуючи git rev-parseотримаєте назву поточної гілки , щоб виключити її. Якщо ви отримали помилку, це означає, що немає локальних гілок, які потрібно видалити.

Щоб зробити те ж саме з віддаленими гілками (змінити originсвоїм віддаленим іменем), спробуйте:

git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)

Якщо у вас є кілька віддалених пристроїв, додайте grep origin |раніше, cutщоб фільтрувати лише origin.

Якщо вищезгадана команда не вдається, спробуйте спочатку видалити об'єднані гілки віддаленого відстеження:

git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

Потім git fetchзнову пульт та знову використовуйте попередню git push -vdкоманду.

Якщо ви використовуєте його часто, розгляньте можливість додавання у ~/.gitconfigфайл псевдонімів .

Якщо ви видалили деякі гілки помилково, використовуйте git reflogдля пошуку втрачених коміксів.


4

На основі деяких з цих відповідей я створив свій власний сценарій Bash, щоб зробити це теж !

Він використовує git branch --mergedта git branch -dвидаляє гілки, які були об'єднані, і підкаже вам для кожної гілки перед видаленням.

merged_branches(){
  local current_branch=$(git rev-parse --abbrev-ref HEAD)
  for branch in $(git branch --merged | cut -c3-)
    do
      echo "Branch $branch is already merged into $current_branch."
      echo "Would you like to delete it? [Y]es/[N]o "
      read REPLY
      if [[ $REPLY =~ ^[Yy] ]]; then
        git branch -d $branch
      fi
  done
}

4

Нижче запит працює для мене

for branch in  `git branch -r --merged | grep -v '\*\|master\|develop'|awk 'NR > 0 {print$1}'|awk '{gsub(/origin\//, "")}1'`;do git push origin --delete $branch; done

і це буде фільтрувати будь-яку галузь в греп-трубі.

Добре працює над http-клоном, але не дуже добре для ssh-з'єднання.


4

Станом на 2018.07

Додайте це до [alias]розділу свого ~/.gitconfig:

sweep = !"f() { git branch --merged | egrep -v \"(^\\*|master|dev)\" || true | xargs git branch -d; }; f"

Тепер ви можете просто зателефонувати, git sweepщоб виконати необхідну очистку.


Для мене виклик git sweep лише перелічує гілки, які слід очистити, але їх не видаляє
Віктор Мораес

4

У Windows з встановленим git bash egrep -v не працюватиме

git branch --merged | grep -E -v "(master|test|dev)" | xargs git branch -d

де grep -E -vеквівалентноegrep -v

Використовуйте -dдля видалення вже об'єднаних гілок або -Dдля видалення незанурених гілок


egrep -v працює для мене. Я використовую gitbash від інсталятора gitextensions
Джо Філліпс

4

Я використовував наступний метод для видалення об'єднаних локальних І віддалених гілок за один cmd.

У моєму bashrcфайлі є таке:

function rmb {
  current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
  if [ "$current_branch" != "master" ]; then
    echo "WARNING: You are on branch $current_branch, NOT master."
  fi
  echo "Fetching merged branches..."
  git remote prune origin
  remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
  local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
  if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
    echo "No existing branches have been merged into $current_branch."
  else
    echo "This will remove the following branches:"
    if [ -n "$remote_branches" ]; then
      echo "$remote_branches"
    fi
    if [ -n "$local_branches" ]; then
      echo "$local_branches"
    fi
    read -p "Continue? (y/n): " -n 1 choice
    echo
    if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
      # Remove remote branches
      git push origin `git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$" | sed 's/origin\//:/g' | tr -d '\n'`
      # Remove local branches
      git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`
    else
      echo "No branches removed."
    fi
  fi
}

оригінальний джерело

Це не видаляє головну гілку, але видаляє об'єднані локальні І віддалені гілки . Після того, як ви маєте це у вашому файлі rc, просто запустіть rmb, вам буде показаний список об'єднаних гілок, які будуть очищені та запитані про підтвердження дії. Ви можете змінити код, щоб він також не вимагав підтвердження, але його, мабуть, добре зберігати.


3

Напишіть сценарій, в якому Git перевіряє всі гілки, які були об'єднані для управління.

Тоді робіть git checkout master.

Нарешті, видаліть об'єднані гілки.

for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
  branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
  echo branch-name: $branchnew
  git checkout $branchnew
done

git checkout master

for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
  branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
  echo branch-name: $branchnew
  git push origin --delete $branchnew
done

3

Прийняте рішення є досить хорошим, але є одне питання, що воно також видаляє локальні гілки, які ще не були об'єднані у віддалений.

Якщо ви подивитеся на результат, ви побачите щось на кшталт

$ git branch --merged master -v
  api_doc                  3a05427 [gone] Start of describing the Java API
  bla                      52e080a Update wording.
  branch-1.0               32f1a72 [maven-release-plugin] prepare release 1.0.1
  initial_proposal         6e59fb0 [gone] Original proposal, converted to AsciiDoc.
  issue_248                be2ba3c Skip unit-for-type checking. This needs more work. (#254)
  master                   be2ba3c Skip unit-for-type checking. This needs more work. (#254)

Гілки blaта issue_248місцеві гілки, які видалялися б мовчки.

Але ви також можете побачити слово [gone], яке вказує на гілки, які були висунуті на віддалений (який уже немає), і таким чином позначення гілок можна видалити.

Таким чином, вихідну відповідь можна змінити на (розділити на багаторядкові для меншої довжини рядка)

git branch --merged master -v | \
     grep  "\\[gone\\]" | \
     sed -e 's/^..//' -e 's/\S* .*//' | \
      xargs git branch -d

для захисту ще не злилися гілок. Також не потрібна пов'язка для майстра, щоб захистити його, оскільки це пульт дистанційного початку і не відображається як зниклий.


3

Для мене git branch --mergedне відображаються гілки, які були об'єднані через GitHub PR. Я не впевнений у причинах, але використовую наступний рядок, щоб видалити всі локальні гілки, які не мають гілки віддаленого відстеження :

diff <(git branch --format "%(refname:short)") <(git branch -r | grep -v HEAD | cut -d/ -f2-) | grep '<' | cut -c 3- | xargs git branch -D

Пояснення:

  • git branch --format "%(refname:short)" дає перелік місцевих відділень
  • git branch -r | grep -v HEAD | cut -d/ -f2- дає список віддалених гілок, фільтруючи HEAD
  • diff <(...) <(...) дає різний вихід двох команд всередині дужок
  • grep '<' фільтрує гілки, які існують у першому списку, а не у другому
  • cut -c 3- дає рядок, починаючи з 3-го символу, тим самим видаляючи префікс <
  • xargs git branch -Dвиконується git branch -Dпроти кожної назви гілки

Також можна уникнути grep -v '<'подібного:

diff --old-line-format="%L" --new-line-format="" --unchanged-line-format="" <(git branch --format "%(refname:short)") <(git branch -r | grep -v HEAD | cut -d/ -f2-) | xargs git branch -D
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.