Birleştirilen tüm Git dallarını nasıl silebilirim?


1935

Git Git şubem var. Zaten birleştirilmiş şubeleri nasıl silebilirim? Hepsini tek tek silmek yerine silmenin kolay bir yolu var mı?


46
Biraz daha açık olmak gerekirse git branch -D, birleştirilmiş olsun olmasın herhangi bir dalı siler.
PhilT

12
Reponunuzun 'şubeler' bölümüne giderseniz (örneğin github.com/<username>/<repo_name>/branches ) bunu doğrudan GitHub'dan da yapabilirsiniz . Tüm şubelerinizin bir listesi bulunmalı, yanda seçilen dalı silecek kırmızı bir çöp tenekesi simgesi olmalıdır. Terminalde yapmaktan çok daha hızlı! Ayrıca masterher dalın ne kadar ilerisinde / arkasında olduğunu gösterecektir . Ancak, çalıştırdığınızda yerel istemciniz eski dalları listeleyecektir git branch -a; git fetch --prunekaldırmak için kullanın ( bu cevaba göre ).
user5359531

3
Bunu yerel olarak veya uzaktan yapmak için komut dosyası - güvenlik denetimleri ve önceden yapılandırılmış "güvenli dallar" ile: github.com/fatso83/dotfiles/tree/master/utils/… git delete-merged --doit origin veyagit delete-merged --doit --local
oligofren

Birleştirilmiş dalları otomatik olarak silmek için de bu uygulamayı kullanabilirsiniz .
Sebass van Boxel

rm -fr work && git clone http://example.com/work.gityıllar boyunca git ile turşudan çıkmanın en kolay yolu haline geldi.
Reactgular

Yanıtlar:


3115

GÜNCELLEME:

İş akışınızda olası bir ata olarak varsa master ve dev gibi hariç tutmak için başka dallar ekleyebilirsiniz. Genellikle bir "sprint-start" etiketinden ayrılıyorum ve master, dev ve qa ata değiller.

İlk olarak, uzaktan birleştirilen tüm dalları listeleyin.

git branch --merged

Kaldırmak istemediğiniz birkaç dal görebilirsiniz. master veya geliştirme gibi silmek istemediğimiz önemli dalları atlamak için birkaç argüman ekleyebiliriz. Aşağıdaki komut ana dalı ve içinde dev olan her şeyi atlar.

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

Atlamak istiyorsanız, egrep komutuna aşağıdaki gibi ekleyebilirsiniz. Şube skip_branch_namesilinmeyecek.

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

Halihazırda kullanıma alınmış şubeye önceden birleştirilen tüm yerel şubeleri silmek için:

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

Bir ata olması durumunda master ve dev'in dışarıda bırakıldığını görebilirsiniz.


Birleştirilmiş bir yerel dalı aşağıdakilerle silebilirsiniz:

git branch -d branchname

Birleştirilmemişse şunu kullanın:

git branch -D branchname

Uzaktan kullanımdan silmek için:

git push --delete origin branchname

git push origin :branchname    # for really old git

Şubeyi uzaktan kumandadan sildikten sonra, uzaktan izleme dallarından kurtulmak için budama yapabilirsiniz:

git remote prune origin

veya diğer yanıtın önerdiği gibi, bireysel uzaktan izleme dallarını budamak için:

git branch -dr branchname

Bu yardımcı olur umarım.


46
UYARI: Yeni bir şube oluşturduysanız, o da bir şube silecektir. En üstteki komutu çalıştırmadan önce listede yeni oluşturulan bir dal bulunmadığından emin olun.
Gary Haran

153
UYARI KABULÜ: reflog pastırmanızı kurtaracaktır. Yani endişelenme.
Adam Dymitruk

33
İlk komutun yalnızca yerel şubeleri sildiğini unutmayın, bu nedenle bazılarının işaret ettiği gibi 'tehlikeli' değildir.
ifightcrime

79
PowerShell varyantı, böylece yanıtı bir dahaki sefere googled burada bulabilirsiniz:git branch --merged | %{$_.trim()} | ?{$_ -notmatch 'develop' -and $_ -notmatch 'master'} | %{git branch -d $_}
vorou

23
fatal: branch name requiredSilinecek şubeniz yoksa , bu bir hata oluşturur . Eğer geçebilir Bunu önlemek için -rhiç xargsyayınlanmaz böylece git branch -dStdin boşsa. (Bu, man sayfasına göre bir GNU xargs uzantısıdır).
Marius Gedminas

457

Uzaktaki birleştirilmiş olan tüm dalları silmek için:

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

Git'in daha yeni sürümlerinde

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

GÜNCELLEME (@oliver tarafından; yoruma uymadığından, ancak zaten yeterli cevap aldığından) : ABC dalındaysanız, ABCgit branch -r --merged , dal belirtilmediğinden , bu nedenle dal varsayılan olarak geçerli dalı ve bir dalı varsayılan olarak gösterir her zaman kendisiyle birleşmiş olarak nitelendirilir (çünkü bir şube ile kendisi arasında hiçbir fark yoktur!).

Ya da dalı belirtin:

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

VEYA ilk ödeme ustası:

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

18
Şimdiye kadar en iyi cevap. Sadece bir not, ana dalım adlandırıldı, devbu yüzden değiştirmek zorunda kaldım
Dorian

41
Diğer uzaktan kumandaların dallarının kökene itilmesini önlemek için daha | grep originsonra eklemek zorunda kaldım grep -v master. Çıktıyı önceden test git branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo
etmenizi şiddetle

9
developŞubeyi de hariç tutmak için biraz değiştirdim . git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin. Şimdi bu benim takma adım oldu.
sarat

8
Bunu okuduğum en iyi cevap -ryapan şey, başka hiçbir yerde bahsetmediğim bir argüman. Sadece yerel şubelerin biraz temizlik yapmaya değer olduğu kabul edilir. Ancak uzaktan kumandalar da çöplerle dolu.
Asbjørn Ulsberg

19
Dikkat - farkettim: Bu besbelli dalları için birleşti bulacaksınız cari dalı değil, usta, üzerinde sen eğer öyleyse myFeatureBrancho silecek origin/myFeatureBranch. Muhtemelen git checkout masterilk önce en iyisi .
jakub.g

190

Adam'ın cevabını biraz uzatmak:

Bunu Git yapılandırmanıza çalıştırarak ekleyin git config -e --global

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

Ve sonra basit bir şekilde tüm yerel birleştirilmiş dalları silebilirsiniz git cleanup.


11
ilk komut olmamalıdır: git branch --merged masterşu anda kullanıma alınmış dal değil, master ile birleştirilen neye bakmak istediğiniz için?
Joe Phillips

@JoePhilllips Bazı insanlar ana dalda usta değil ama bunun yerine developveya devbu durumda komut başarısız olur, fatal: malformed object namegenel bir komut almak daha iyidir ve bunu yürütme sorumluluğunuz vardır
Ağustos'ta

1
@JoePhilllips bu cevabın amacı Adam'ın cevabını (bu sorunun en iyi cevabı) faydalı git takma isminde paketlemektir. Adam'ın cevabı sizin önerdiğiniz şeye sahip değil ve birçok insan bunu faydalı buldu, bu yüzden benimkini değiştirmemeye meyilli olacağım. Bu konuda güçlü bir şekilde hissediyorsanız Adam'ın cevabı hakkındaki tartışmayı açmanızı tavsiye ederim
real_ate

13
Eklenmesi -r, bu takma adı birden çok kez çalıştırdığınızda veya silinecek hiçbir şube kalmadığında xargsgereksiz hataları ( branch name required) önleyecektir . Takma cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d"
adım

1
Şu anki komut efendiyi filtrelemiyor ve şubeleri geliştirmiyor
Andriy F.

83

Bu, master hariç tüm birleştirilmiş dalları da siler.

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

3
Şimdi içindeki herhangi bir dalı silmeyecek master. Ortayı deneyin grep -v ^master$.
wchargin

| grep -v '^\*'Eğer usta
svassr

5
Harika, teşekkürler! Bunu kullanan herkes için bir uyarı: içinde iki boşluk olduğunu unutmayın grep -v '^ master$'. Kendinize yazar ve bir tanesini kaçırırsanız, üzerinde değilseniz silersiniz master.
14'te styger

3
@ Mr.Polywhirl düzenlemeniz komutu kırar ve geri almalısınız. İki boşluk gereklidir, çünkü git brancho anda teslim alınmış dal değilse, her bir dal adını solda iki boşluk bulunan yeni bir satırda listeleyecektir. Bu komutu çalıştıran herkesin, şu anda kullanıma alınmış dal olmadığı sürece ana dallarını sileceğini garanti ettiniz.
15'te styger

79

master& developDallarını bu komutların dışında bırakmak isteyeceksiniz .

Yerel git temizle:

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

Uzaktan git temizle:

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

Uzak şubelerin yerel kayıt defterini senkronize et:

git fetch -p

3
Uzak sürüm için +1 de (ancak uzaktan kumandaya sahip olduğumuz için daha az gerekli). Ayrıca thoose eski git sürümü ile çalışmaz
malko

4
git config --global --add fetch.prune truegetirme veya çekme sırasında otomatik olarak budama.
T3rm1

1
Dikkat edin, kuru erik uzaktan kumandayla aynı değildir. Remote clear aslında mevcut dalınızla tamamen birleştirilen uzak dalları siler. Prune, yalnızca önceden silinmiş uzak dalların yerel kayıt defterini temizler.
Guido Bouman

Şube daha önce birleştirildiğinde birleştirilmiş olarak kabul edileceğinden, ancak birleştirilmeden sonra birleştirmeden sonra yeni taahhütlere sahip olacağından, kelime tamamen yanıltıcıdır.
çörekler

Bir çağrıda tüm git branch -r --merged | grep -v '\*\|master\|develop' | grep '^\s*origin/' | sed 's/origin\///' | tr "\n" " " | xargs git push --delete origin
köklü

48

Windows'ta olan ve PowerShell komut dosyalarını tercih edenleriniz için, yerel birleştirilmiş şubeleri silenler:

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

13
Merak uğruna, bu kısaltılabilir git branch --merged | ?{-not ($_ -like "*master")} | %{git branch -d $_.trim()}
Iain Ballard

5
@IainBallard Tabii, takma ad kullanabilirdim. Okunabilirliği en üst düzeye çıkarmak istediğinizde önerilmez. github.com/darkoperator/PSStyleGuide/blob/master/English.md
Klas Mellbourn

1
Elbette. Cevabınızı çok yararlı buldum :-) Ancak bazen uzun biçimli powershell sözdizimi bloklarda neler olup bittiğini engelliyor. Ama öncelikle, bir kereye mahsus olarak kopyalayabileceğiniz / yapıştırabileceğiniz veya yazabileceğiniz bir şey öne sürüyordum. Tekrar teşekkürler.
Iain Ballard

4
İşte ustayı ve mevcut for /f "usebackq" %B in (``git branch --merged^|findstr /v /c:"* " /c:"master"``) do @git branch -d %Bdalınızı koruyan Windows cmd kabuğu için bir astar: (iç çek, çift backquotes'u tek yerine değiştirin, backquotes içeren bir değişmezi nasıl biçimlendireceğinizden emin değilim)
yoyo

42

Adam'ın cevabını yıllardır kullanıyorum. Bununla birlikte, beklediğim gibi davranmadığı bazı durumlar olduğunu söyledi:

  1. "ana" kelimesini içeren şubeler dikkate alınmadı, örneğin yalnızca ana dal yerine "notmaster" veya "usta"
  2. "dev" kelimesini içeren dallar, yalnızca geliştirici daldan ziyade "dev-test" olarak göz ardı edildi.
  3. geçerli şubenin HEAD'ından ulaşılabilen dalları silme (yani, mutlaka master olması gerekmez)
  4. mevcut HEAD durumundan erişilebilen her dalı silme

1 & 2, regex'te sadece bir değişiklikle doğrudan anlaşılabilirdi. 3, ne istediğinizin içeriğine bağlıdır (örneğin, yalnızca ana sisteme veya mevcut şubenize karşı birleştirilmemiş dalları silin). git reflogEğer istemeden HEAD durumunda çalıştırırsanız, 4'ün (kurtarılabilir olmasına rağmen ) felaket olma potansiyeli vardır .

Son olarak, bunun ayrı bir (Bash | Ruby | Python) komut dosyası gerektirmeyen tek satırda olmasını istedim.

TL; DR

İsteğe bağlı -fbayrağı kabul eden bir git takma adı "süpürme" oluşturun :

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

ve şununla çağır:

git sweep

veya:

git sweep -f

Uzun, ayrıntılı cevap

Benim için en kolay yoldan bazı dalları ile git repo oluşturmak ve doğru davranışı test etmek için taahhüt:

Tek bir taahhütle yeni bir git repo oluşturun

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

Yeni şubeler oluşturun

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

İstenen davranış: ana, geliştirme veya akım hariç tüm birleştirilmiş şubeleri seçin

Orijinal regex "usta" ve "notmaster" dallarını özlüyor:

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

Güncellenmiş normal ifadeyle (şimdi "dev" yerine "geliştirme" yi hariç tutuyor):

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

Şube foo'ya geçin, yeni bir taahhütte bulunun, ardından foo'ya dayalı yeni bir şube, foobar atın:

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

Geçerli şubem foobar ve silmek istediğim dalları listelemek için yukarıdaki komutu yeniden çalıştırırsam, "foo" dalı master ile birleştirilmemiş olsa da dahil edilir:

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

Ancak, master üzerinde aynı komutu çalıştırırsanız, şube "foo" dahil değildir:

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

Bunun nedeni git branch --merged, aksi belirtilmedikçe, geçerli dalın HEAD'inin varsayılan değerlerinin olmasıdır. En azından benim iş akışı için, master için birleştirilmedikçe yerel şubeleri silmek istemiyorum, bu yüzden aşağıdaki varyantı tercih ediyorum:

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

Müstakil HEAD durumu

Varsayılan davranışına güvenmek, git branch --mergedayrılmış HEAD durumunda daha da önemli sonuçlara yol açar:

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

Bu, ben sadece "foobar" ile birlikte "foo" ile birlikte, neredeyse kesinlikle istenen sonuç değildir şube silecek olurdu. Bununla birlikte, revize edilmiş komutumuzla:

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

Gerçek silme dahil bir satır

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

Tüm bir git takma "süpürme" içine sarılmış:

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

Takma ad isteğe bağlı bir -fbayrağı kabul eder . Varsayılan davranış, yalnızca kalıpla birleştirilen dalları silmektir, ancak -fbayrak geçerli dalla birleştirilen dalları siler.

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

Neden bir işlev oluşturmanız gerekiyor? git configAtomik değil mi?
VasiliNovikov

İsteğe bağlı '-f' argümanıyla başa çıkmak için (eğer sorunuzu doğru
eddies

1
ama nasıl yardımcı olur? Yani ifadenin başlangıcı !f(){ git branch .... Bu bir işlev beyanı, değil mi? Neden doğrudan başlamıyorsunuz git branch ...?
VasiliNovikov

1
Kesinlikle haklısın. Cevabımı buna göre düzenledi. İşaretçi için teşekkürler!
eddies

Aşağıdakiler zorlama modu ile aynı olmaz mı? git checkout master && git branch -d `git branch --merged` && git checkout - Bunun haricinde silinebilir develop, ancak daha basit bir yaklaşım olabilir.
Guido Bouman


18

Git sürüm 2.5.0'ı kullanma:

git branch -d `git branch --merged`

16
Bu masterşube btw silebilirsiniz !
Wazery

4
Doğru. Sadece emin olduğum zaman kullanıyorum master.
drautb

11
git branch -d $(git branch --merged | grep -v master)
alexg

1
Akışınız varsa bu tehlikelidir, master <- stage <- dev. Hala en kolay çözüm imo
Joseph Briggs

14

Taahhüt işlemini --merged seçeneğine ekleyebilirsiniz. Bu şekilde yalnızca orijin / master ile birleştirilen dalları kaldırdığınızdan emin olabilirsiniz.

Aşağıdaki komut, birleştirilmiş dalları menşeinizden kaldıracaktır.

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

Git push orijini ile silip hangi dalların kaldırılacağını test edebilirsiniz echo ile silin

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

2
Test seçeneğini seviyorum
iwein

12

Zaten birleştirilmiş yerel ve uzak şubelerimi silmek için aşağıdaki Ruby komut dosyasını kullanıyorum. Birden çok uzaktan kumandalı bir havuz için yapıyorum ve yalnızca birinden silmek istiyorsanız, sadece istediğim uzaktan kumandaları almak için uzaktan kumanda listesine bir select deyimi ekliyorum.

#!/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

Bu git küçük bir yardımcı kütüphane için çalmak ister misin? github.com/yupiq/git-branch-util
logan

1
Kodunu bir şekilde yeniden kullanan insanları
önemseseydim, buraya koymazdım

@mmrobins Satır \/için reddetme ifadesinin başında fazladan bir paranız var remote_branches. Bu bir yazım hatası mı yoksa bir amaca mı hizmet ediyor?
Cevat

@mmrobins, oh boşver b.split(/\//)şimdi çizgiyi görüyorum
Jawwad

Temel olarak bunu yapmak istiyorsanız, ancak yakut yerine vanilya bash ile: stackoverflow.com/a/37999948/430128
Raman

11

PowerShell konsolunda birleştirilmiş şubeler nasıl silinir

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

Master veya diğer şube adlarını hariç tutmak istiyorsanız, PowerShell Select-String ile böyle bir boru oluşturabilir ve sonucu şuraya aktarabilirsiniz git branch -d:

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

1
Daha yüksek yanıtlar, master veya diğer dalları filtrelemeyi önermektedir. Powershell bunu yapmak isteyenler için: git branch --merged | findstr / v "usta" | % {git branch -d $ _. trim ()}
tredzko

@tredzko İyi bir nokta. FTR daha yüksek cevap stackoverflow.com/questions/6127328/… - bu bağlantılı ile yorumunuzu yeniden gönderebilir ve daha sonra bunu silmek istiyorum
Ruben Bartelink

ayrıca silmeye çalışır * master:)
iesen

9

Kuboon'un cevabı, şube adında master kelimesi olan dalları sildi. Cevabı şu şekilde gelişir:

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

Tabii ki, "ana" dal kendini silmez :)


8

Git'te bunu sizin için otomatik olarak yapacak bir komut yoktur. Ancak size ihtiyacınız olanı vermek için Git komutlarını kullanan bir komut dosyası yazabilirsiniz. Bu, hangi dallanma modelini kullandığınıza bağlı olarak birçok şekilde yapılabilir.

Bir dalın master ile birleştirilip birleştirilmediğini bilmeniz gerekiyorsa, myTopicBranch birleştirilirse aşağıdaki komut hiçbir çıkış vermez (yani silebilirsiniz)

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

Git dal komutunu kullanabilir ve Bash'deki tüm dalları ayrıştırabilir ve tüm dallarda bir fordöngü yapabilirsiniz . Bu döngüde, yukarıdaki komutu silerek silip silemeyeceğinizi kontrol edersiniz.



7

Not : Önceki yanıtlardan memnun değilim (tüm sistemlerde çalışmıyor, uzaktan kumandada çalışmıyor, --merged dalı belirtmiyor, tam olarak filtrelemiyor). Bu yüzden kendi cevabımı ekliyorum.

İki ana durum vardır:

Yerel

Sen isteyen yerel şubesi silmek edilir zaten başka bir şubesine birleşti . Silme işlemi sırasında, usta, geliştirme vb. Gibi bazı önemli dalları tutmak istersiniz.

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

Notlar :

  • git branch output --format "..", boşlukları sıyırmak ve tam grep eşleşmesine izin vermektir
  • grep -Eyerine kullanılır egrep, bu nedenle egrep olmayan sistemlerde de çalışır (örn: pencereler için git).
  • grep -E -v '^master$|^feature/develop$' silmek istemediğim yerel şubeleri belirtmektir
  • xargs -n 1 git branch -d: yerel şubelerin silinmesini gerçekleştirir (uzaktaki şubelerde çalışmaz)
  • Elbette , şu anda kullanıma alınmış olan şubeyi silmeye çalışırsanız bir hata alırsınız. Bu yüzden, önceden ustaya geçmenizi öneririm.

uzak

Sen istediğiniz uzak dalları silmek edilir zaten başka uzak şubesine birleşti . Silme işlemi sırasında HEAD, master, sürümler vb. Gibi bazı önemli dalları tutmak istersiniz.

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

Notlar :

  • uzaktan kumanda için, -rseçeneği kullanırız ve tam şube adını veririz :origin/master
  • grep -E -v '^*HEAD$|^*/master$|^*release' silmek istemediğimiz uzak dalları eşleştirmektir.
  • cut -d/ -f2-: aksi takdirde git branchkomut tarafından yazdırılan gereksiz 'origin /' önekini kaldırın .
  • xargs -n 1 git push --delete origin : uzak dalların silinmesini gerçekleştirir.

7

Windows kullanıyorsanız , güzel bir dal listesine sahip olmak ve silmek istediğiniz fareyi seçmek için Out-GridView ile Windows Powershell veya Powershell 7'yi kullanabilirsiniz :

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

resim açıklamasını buraya girin Tamam'ı tıkladıktan sonra Powershell bu dalların adlarını git branch -dkomut vermek ve silmek için geçirecekresim açıklamasını buraya girin


6

git-del-br Aracı kullanabilirsiniz .

git-del-br -a

Sen aracılığıyla yükleyebilirsiniz pipkullanarak

pip install git-del-br

PS: Aracın yazarıyım. Herhangi bir öneri / geribildirim bekliyoruz.


1
@ stackoverflow.com/users/100297/martijn-pieters : Bu cevap neden silindi ve reddedildi?
tusharmakkar08

1
Cevabınız ve aracınız çalışmıyor. Üzerinde birkaç saat geçiriyorum. Hiçbir şey değil.
SpoiledTechie.com

@ SpoiledTechie.com: Bana tam olarak hangi problemle karşı karşıya olduğunuzu söyleyebilir misiniz? Düzenli olarak kullanıyorum.
Eylül 17:53

Bu çevrimdışı duruma getirmek isterseniz bir ekran görüntüsünü paylaşabilir miyim? o posta postasında spoiledtechie. :)
SpoiledTechie.com

5

Halihazırda bulunduğunuz şubeye önceden birleştirilmiş tüm yerel şubeleri silmek istiyorsanız, önceki yanıtlara dayanarak bunu yapmak için güvenli bir komut buldum:

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

Bu komut geçerli dalınızı veya ana dalınızı etkilemez. Ayrıca xargs'ın -t bayrağını kullanarak, yapmadan önce ne yaptığını da size söyleyecektir.


5

Adem'in güncellenmiş cevabının takma adı sürümü :

[alias]
    branch-cleanup = "!git branch --merged | egrep -v \"(^\\*|master|dev)\" | xargs git branch -d #"

Ayrıca, karmaşık takma adlardan kaçmak için kullanışlı ipuçları için bu cevaba bakın .


5

Git-flow esque adlandırma düzeni kullanıyorum, bu yüzden bu benim için çok güvenli bir şekilde çalışıyor:

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

Temelde dize fix/veya ile başlayan birleştirilmiş taahhütleri arar feature/.


4

Aşağıdaki komutu deneyin:

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

Kullanarak mevcut şube adını hariç tutmak için git rev-parsealırsınız . Hatayı aldıysanız, kaldırılacak yerel şube olmadığı anlamına gelir.

Aynı şeyi uzak dallarla yapmak için ( originuzak adınızla değiştirin ) şunu deneyin:

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

Eğer birden fazla kumanda ettik durumda, ekleme grep origin |önce cutsadece filtreye origin.

Yukarıdaki komut başarısız olursa, önce birleştirilmiş uzaktan izleme dallarını silmeyi deneyin:

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

Ardından git fetchuzaktan kumandayı tekrarlayın ve önceki git push -vdkomutu tekrar kullanın .

Sık sık kullanıyorsanız, ~/.gitconfigdosyanıza takma ad olarak eklemeyi düşünün .

Bazı şubeleri yanlışlıkla git reflogsildiyseniz, kayıp taahhütleri bulmak için kullanın .


4

Bu cevapların bazılarına dayanarak ben de kendi Bash betiğimi yaptım !

Birleştirilen dalları silmek için git branch --mergedve kullanır ve git branch -dsilmeden önce dalların her birini ister.

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

Aşağıdaki sorgu benim için çalışıyor

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

ve bu grep borusundaki herhangi bir dalı filtreleyecektir.

Http klonu üzerinde iyi çalışır, ancak ssh bağlantısı için çok iyi değildir.


4

2018 itibariyle

Bunu, [alias]bölümünüze ekleyin ~/.gitconfig:

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

Şimdi sadece git sweepgerekli temizliği yapmak için arayabilirsiniz .


Benim için git süpürme sadece temizlenmesi gereken dalları listeler, ancak onları kaldırmaz
Victor Moraes

4

Git bash yüklü Windows'ta egrep -v çalışmaz

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

nerede grep -E -veşdeğeregrep -v

-dZaten birleştirilmiş olanları kaldırmak için kullanın şube veya -Dkaldırmak için birleştirilmemiş dalları


egrep -v benim için çalışıyor. Gitextensions yükleyicisinden gitbash kullanıyorum
Joe Phillips

4

Bir cmd birleştirilmiş yerel VE uzak dalları kaldırmak için aşağıdaki yöntemi kullanıyorum .

Dosyamda aşağıdakiler var 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
}

orijinal kaynak

Bu, ana dalı silmez, ancak birleştirilmiş yerel VE uzak dalları kaldırır . Eğer rc dosyasında bu var, sadece çalıştırın rmb, size temizlenir ve eylem onayı istenecek birleştirilmiş şubelerin bir listesi gösterilir. Kodu da onay istemeyecek şekilde değiştirebilirsiniz, ancak büyük olasılıkla saklamak iyidir.


3

Git'in master ile birleştirilen tüm dalları kontrol ettiği bir komut dosyası yazın.

Öyleyse yap git checkout master.

Son olarak, birleştirilen dalları silin.

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

Kabul edilen çözüm oldukça iyi, ancak henüz bir uzaktan kumanda ile birleştirilmemiş yerel şubeleri de silmesi gereken tek sorun var.

Çıktınıza bakarsanız şöyle bir şey göreceksiniz

$ 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)

Şubeler blave issue_248sessizce silinecek yerel şubelerdir.

Ama kelimesini de görebilirsiniz [gone] bir uzaktan kumandaya itilen dalları (şimdi gitti) gösteren ve böylece şubelerin silinebileceğini gösteren .

Böylece orijinal cevap değiştirilebilir (daha kısa hat uzunluğu için çok satıra bölünebilir)

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

henüz birleştirilmiş olmayan dalları korumak için. Ayrıca, ustanın onu korumak için selamlamak gerekmez, çünkü bu kökeninde bir uzaktan kumandaya sahiptir ve gittiği gibi görünmez.


3

Benim için git branch --mergedGitHub PR aracılığıyla birleştirilen şubeleri göstermiyorum. Nedenlerinden emin değilim, ancak uzaktan izleme dalı olmayan tüm yerel şubeleri silmek için aşağıdaki satırı kullanıyorum :

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

Açıklama:

  • git branch --format "%(refname:short)" yerel şubelerin bir listesini verir
  • git branch -r | grep -v HEAD | cut -d/ -f2- filtreleyen uzak dalların bir listesini verir HEAD
  • diff <(...) <(...) parantez içindeki iki komutun çıktısını verir
  • grep '<' ilk listede var olan ancak ikinci listede olmayan dalları filtreler
  • cut -c 3- 3. karakterden başlayarak satır verir, böylece önek kaldırılır <
  • xargs git branch -Dgit branch -Dher şube adına karşı yürütür

Alternatif olarak, aşağıdakilerden kaçınabilirsiniz 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.