Bagaimana saya bisa menghapus semua cabang Git yang telah digabungkan?

1936

Saya memiliki banyak cabang Git. Bagaimana cara saya menghapus cabang yang sudah digabung? Apakah ada cara mudah untuk menghapus semuanya alih-alih menghapusnya satu per satu?

Nyambaa
sumber
46
Untuk menjadi sedikit lebih spesifik git branch -Dmenghapus cabang apa pun apakah itu telah digabung atau tidak.
PhilT
12
Anda juga dapat melakukan ini langsung dari GitHub, jika Anda pergi ke bagian 'cabang' dari repo Anda (mis. Github.com/<username>/<repo_name>/branches ). Seharusnya ada daftar semua cabang Anda, dengan ikon tempat sampah merah di samping yang akan menghapus cabang yang dipilih. Jauh lebih cepat daripada melakukannya di terminal! Juga akan menunjukkan seberapa jauh di depan / di belakang mastersetiap cabang. Namun, klien lokal Anda masih akan mencantumkan cabang lama jika Anda menjalankan git branch -a; gunakan git fetch --pruneuntuk menghapusnya (sesuai jawaban ini ).
user5359531
3
Script untuk melakukan ini secara lokal atau jarak jauh - dengan pemeriksaan keamanan dan "cabang aman" yang telah dikonfigurasi sebelumnya: github.com/fatso83/dotfiles/tree/master/utils/… git delete-merged --doit origin orgit delete-merged --doit --local
oligofren
Anda juga dapat menggunakan aplikasi ini untuk menghapus cabang yang digabung secara otomatis.
Sebass van Boxel
rm -fr work && git clone http://example.com/work.gitselama bertahun-tahun telah menjadi cara termudah untuk keluar dari acar dengan git.
Reactgular

Jawaban:

3116

MEMPERBARUI:

Anda dapat menambahkan cabang lain untuk dikecualikan seperti master dan dev jika alur kerja Anda memiliki mereka sebagai leluhur yang mungkin. Biasanya saya bercabang dari tag dan master "sprint-start", dev dan qa bukan leluhur.

Pertama, daftarkan semua cabang yang digabungkan dalam jarak jauh.

git branch --merged

Anda mungkin melihat beberapa cabang yang tidak ingin Anda hapus. kita dapat menambahkan beberapa argumen untuk melewati cabang-cabang penting yang tidak ingin kita hapus seperti master atau pengembangan. Perintah berikut akan melewati cabang master dan apa pun yang memiliki dev di dalamnya.

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

Jika Anda ingin melewati, Anda dapat menambahkannya ke perintah egrep seperti berikut ini. Cabang skip_branch_nametidak akan dihapus.

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

Untuk menghapus semua cabang lokal yang sudah bergabung ke cabang yang sedang diperiksa:

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

Anda dapat melihat bahwa master dan dev dikecualikan jika mereka adalah leluhur.


Anda dapat menghapus cabang lokal gabungan dengan:

git branch -d branchname

Jika tidak digabungkan, gunakan:

git branch -D branchname

Untuk menghapusnya dari penggunaan jarak jauh:

git push --delete origin branchname

git push origin :branchname    # for really old git

Setelah Anda menghapus cabang dari jarak jauh, Anda dapat memangkas untuk menyingkirkan cabang pelacakan jarak jauh dengan:

git remote prune origin

atau pangkas cabang pelacakan jarak jauh individual, seperti yang disarankan jawaban lain, dengan:

git branch -dr branchname

Semoga ini membantu.

Adam Dymitruk
sumber
46
PERINGATAN: Jika Anda baru saja membuat cabang, cabang itu juga akan dihapus. Pastikan untuk tidak memiliki cabang yang baru dibuat dalam daftar sebelum Anda menjalankan perintah paling atas.
Gary Haran
154
OPPOSITE OF WARNING: reflog akan menghemat bacon Anda. Jadi jangan khawatir.
Adam Dymitruk
33
Ingatlah bahwa perintah pertama hanya menghapus cabang lokal, jadi itu tidak 'berbahaya' seperti yang ditunjukkan beberapa orang.
ifightcrime
79
Varian PowerShell, sehingga saya dapat menemukannya di sini lain kali saya mencari jawabannya di Google:git branch --merged | %{$_.trim()} | ?{$_ -notmatch 'develop' -and $_ -notmatch 'master'} | %{git branch -d $_}
vorou
23
Ini menghasilkan kesalahan fatal: branch name requiredjika Anda tidak memiliki cabang yang harus dihapus. Untuk menghindari itu, Anda dapat meneruskan -rke xargssehingga tidak akan berjalan git branch -djika stdin kosong. (Ini ekstensi GNU xargs, menurut halaman manual).
Marius Gedminas
457

Untuk menghapus semua cabang pada jarak jauh yang sudah digabungkan:

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

Di Git versi terbaru

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

UPDATE (oleh @oliver; karena tidak cocok dalam komentar, tetapi sudah cukup jawaban) : jika Anda berada di cabang ABC maka ABC akan muncul di hasilgit branch -r --merged karena cabang tidak ditentukan, jadi cabang default ke cabang saat ini, dan cabang selalu memenuhi syarat sebagai digabungkan ke dirinya sendiri (karena tidak ada perbedaan antara cabang dan dirinya sendiri!).

Jadi tentukan cabang:

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

ATAU master checkout pertama:

git checkout master | git branch -r --merged | grep -v ...
kuboon
sumber
18
Jawaban terbaik sejauh ini. Sekedar catatan, cabang master saya dinamai devjadi saya harus mengubahnya
Dorian
41
Saya harus menambahkan | grep originsetelah grep -v masteruntuk mencegah mendorong cabang remote lainnya ke asal. Sangat merekomendasikan pengujian output sebelumnya, menggunakangit branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo
L0LN1NJ4
9
Saya sedikit dimodifikasi untuk mengecualikan developcabang juga. git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin. Sekarang ini ternyata alias saya.
sarat
8
Apa yang membuat ini jawaban terbaik yang pernah saya baca, adalah -rargumen, yang saya tidak pernah lihat disebutkan di tempat lain. Dianggap begitu saja bahwa hanya cabang lokal yang layak melakukan pembersihan. Tapi remote juga penuh dengan sampah.
Asbjørn Ulsberg
19
Perhatian - baru sadar: ini jelas akan menemukan cabang digabung ke cabang saat ini , bukan master, jadi jika Anda berada di myFeatureBranchsana akan menghapus origin/myFeatureBranch. Mungkin yang terbaik adalah yang git checkout masterpertama.
jakub.g
190

Hanya sedikit memperluas jawaban Adam:

Tambahkan ini ke konfigurasi Git Anda dengan menjalankan git config -e --global

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

Dan kemudian Anda dapat menghapus semua cabang gabungan lokal melakukan hal yang sederhana git cleanup.

real_ate
sumber
11
bukankah seharusnya perintah pertama adalah: git branch --merged masterkarena Anda ingin melihat apa yang telah digabung menjadi master, saat ini tidak memeriksa cabang?
Joe Phillips
@JoePhilllips Beberapa orang memiliki cabang utama bukan master tetapi sebaliknya developatau devdan dalam hal itu perintah akan gagal dengan fatal: malformed object namelebih baik memiliki perintah generik dan Anda memiliki tanggung jawab untuk menjalankannya
smohamed
1
@ JoPhilllips inti dari jawaban ini adalah untuk mengemas jawaban Adam (jawaban teratas untuk pertanyaan ini) dalam alias git yang bermanfaat. Jawaban Adam tidak memiliki apa yang Anda sarankan dan begitu banyak orang telah menemukan bahwa berguna jadi saya akan cenderung untuk tidak mengubah milik saya. Saya akan merekomendasikan membuka diskusi tentang jawaban Adam jika Anda merasa kuat tentang hal itu
real_ate
13
Menambahkan -rke xargsakan mencegah kesalahan yang tidak perlu ( branch name required) ketika menjalankan alias ini beberapa kali atau ketika tidak ada cabang yang tersisa untuk dihapus. Alias ​​saya terlihat seperti ini:cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d"
spezifanta
1
Perintah saat ini tidak menyaring master dan mengembangkan cabang
Andriy F.
83

Ini juga berfungsi untuk menghapus semua cabang gabungan kecuali master.

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d
Ismael Abreu
sumber
3
Sekarang tidak akan menghapus cabang apa pun masterdi dalamnya. Coba grep -v ^master$untuk yang tengah.
wchargin
Saya juga membiarkan | grep -v '^\*'untuk menghindari menghapus cabang saat ini jika Anda tidak
svassr
5
Ini bagus, terima kasih! Satu peringatan untuk siapa pun yang menggunakan ini: perhatikan bahwa ada dua ruang di grep -v '^ master$'. Jika Anda mengetiknya sendiri dan melewatkannya, Anda akan menghapusnya masterjika tidak ada.
styger
3
@ Mr.Polywhirl hasil edit Anda melanggar perintah dan Anda harus mengembalikannya. Dua spasi diperlukan, karena git branchakan mencantumkan setiap nama cabang pada baris baru dengan dua spasi di sebelah kiri jika bukan cabang yang saat ini dicentang. Anda pada dasarnya telah menjamin bahwa siapa pun yang menjalankan perintah ini akan menghapus cabang master mereka kecuali jika itu adalah cabang yang sedang diperiksa.
styger
79

Anda ingin mengecualikan master& developcabang dari perintah itu.

Git lokal jelas:

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

Remote git hapus:

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

Sinkronkan registry lokal dari cabang jarak jauh:

git fetch -p
Guido Bouman
sumber
3
+1 untuk versi jarak jauh juga (tetapi kurang dibutuhkan karena kita memiliki --prune jarak jauh). Juga patut dicatat bahwa mereka tidak akan bekerja dengan versi git yang lebih lama
malko
4
git config --global --add fetch.prune trueuntuk memangkas secara otomatis saat mengambil atau menarik.
T3rm1
1
Pikiran Anda, pangkas tidak sama dengan jarak jauh yang jelas. Remote clear sebenarnya menghapus cabang jarak jauh yang sepenuhnya digabung dengan cabang Anda saat ini. Prune hanya membersihkan registry lokal Anda dari cabang-cabang jarak jauh yang sudah dihapus.
Guido Bouman
Kata sepenuhnya agak menyesatkan, karena cabang akan dianggap bergabung, ketika itu digabung sebelumnya, tetapi memiliki komitmen baru setelah penggabungan, yang tidak digabungkan.
scone
Untuk menghapus semua remote asal dalam satu panggilan, saya menggunakan ini:git branch -r --merged | grep -v '\*\|master\|develop' | grep '^\s*origin/' | sed 's/origin\///' | tr "\n" " " | xargs git push --delete origin
GPHemsley
48

Bagi Anda yang ada di Windows dan lebih suka skrip PowerShell, berikut adalah yang menghapus cabang gabungan lokal:

function Remove-MergedBranches
{
  git branch --merged |
    ForEach-Object { $_.Trim() } |
    Where-Object {$_ -NotMatch "^\*"} |
    Where-Object {-not ( $_ -Like "*master" )} |
    ForEach-Object { git branch -d $_ }
}
Klas Mellbourn
sumber
13
Demi rasa ingin tahu, ini dapat disingkat menjadi git branch --merged | ?{-not ($_ -like "*master")} | %{git branch -d $_.trim()}
Iain Ballard
5
@ IainBallard Tentu, saya bisa menggunakan alias. Itu tidak disarankan ketika Anda ingin memaksimalkan keterbacaan. github.com/darkoperator/PSStyleGuide/blob/master/English.md
Klas Mellbourn
1
Tentu. Saya menemukan jawaban Anda sangat membantu :-) Namun terkadang sintaks PowerShell bentuk panjang menghalangi apa yang terjadi di blok. Tapi terutama, saya mengedepankan sesuatu yang dapat Anda salin / tempel atau ketik satu kali. Terima kasih lagi.
Iain Ballard
4
Berikut ini adalah satu-liner untuk Windows cmd shell yang mempertahankan master dan cabang Anda saat ini: for /f "usebackq" %B in (``git branch --merged^|findstr /v /c:"* " /c:"master"``) do @git branch -d %B(mendesah, ganti double-backquotes dengan single, saya tidak yakin bagaimana memformat literal yang berisi backquotes)
yoyo
42

Saya telah menggunakan jawaban Adam selama bertahun-tahun sekarang. Yang mengatakan, bahwa ada beberapa kasus di mana itu tidak berperilaku seperti yang saya harapkan:

  1. cabang yang berisi kata "master" diabaikan, mis. "notmaster" atau "masterful", daripada hanya cabang master
  2. cabang-cabang yang berisi kata "dev" diabaikan, misalnya "dev-test", bukan hanya cabang dev
  3. menghapus cabang yang dapat dijangkau dari KEPALA cabang saat ini (yaitu, belum tentu menguasai)
  4. dalam keadaan HEAD terpisah, menghapus setiap cabang yang dapat dijangkau dari komit saat ini

1 & 2 langsung ditangani, hanya dengan perubahan pada regex. 3 tergantung pada konteks yang Anda inginkan (yaitu hanya menghapus cabang yang belum digabungkan menjadi master atau melawan cabang Anda saat ini). 4 berpotensi menjadi bencana (walaupun dapat dipulihkan dengan git reflog), jika Anda menjalankannya secara tidak sengaja dalam kondisi HEAD yang terlepas.

Akhirnya, saya ingin semua ini berada dalam satu liner yang tidak memerlukan skrip (Bash | Ruby | Python) terpisah.

TL; DR

Buat alias git "sapuan" yang menerima -fbendera opsional :

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

dan memohonnya dengan:

git sweep

atau:

git sweep -f

Jawaban panjang dan terperinci

Itu yang paling mudah bagi saya untuk membuat contoh git repo dengan beberapa cabang dan berkomitmen untuk menguji perilaku yang benar:

Buat git repo baru dengan komit tunggal

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

Buat beberapa cabang baru

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

Perilaku yang diinginkan: pilih semua cabang digabung kecuali: master, mengembangkan atau saat

Regex asli melewatkan cabang "masterful" dan "notmaster":

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

Dengan regex yang diperbarui (yang sekarang tidak termasuk "berkembang" daripada "dev"):

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

Beralih ke foo cabang, buat komit baru, lalu checkout cabang baru, foobar, berdasarkan foo:

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

Cabang saya saat ini adalah foobar, dan jika saya menjalankan kembali perintah di atas untuk mendaftar cabang yang ingin saya hapus, cabang "foo" dimasukkan walaupun belum digabung menjadi master:

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

Namun, jika saya menjalankan perintah yang sama pada master, cabang "foo" tidak termasuk:

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

Dan ini hanya karena git branch --mergeddefault ke KEPALA cabang saat ini jika tidak ditentukan. Setidaknya untuk alur kerja saya, saya tidak ingin menghapus cabang lokal kecuali mereka telah digabungkan untuk dikuasai, jadi saya lebih suka varian berikut:

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

Keadaan HEAD terlepas

Mengandalkan perilaku default git branch --mergedmemiliki konsekuensi yang bahkan lebih signifikan dalam keadaan HEAD terpisah:

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

Ini akan menghapus cabang saya, "foobar" bersama dengan "foo", yang hampir pasti bukan hasil yang diinginkan. Namun, dengan perintah revisi kami:

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

Satu baris, termasuk penghapusan aktual

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

Semua dibungkus menjadi alias git "sapuan":

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

Alias ​​menerima -fbendera opsional . Perilaku default adalah hanya menghapus cabang yang telah digabungkan ke master, tetapi -fbendera akan menghapus cabang yang telah digabungkan ke cabang saat ini.

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).
pusaran
sumber
Mengapa Anda perlu membuat fungsi? Bukankah git configatom?
VasiliNovikov
Untuk menangani argumen '-f' opsional (jika saya memahami pertanyaan Anda dengan benar)
eddies
1
tetapi bagaimana itu membantu? Maksud saya awal dari ekspresi !f(){ git branch ...,. Ini adalah deklarasi fungsi, kan? Mengapa tidak memulai secara langsung git branch ...?
VasiliNovikov
1
Anda benar sekali. Sunting jawaban saya sesuai dengan itu. Terima kasih untuk penunjuknya!
pusaran
Apakah yang berikut tidak akan melakukan hal yang sama dengan mode non-gaya? git checkout master && git branch -d `git branch --merged` && git checkout - Kecuali itu akan dihapus develop, tetapi mungkin pendekatan yang lebih sederhana.
Guido Bouman
18

Menggunakan Git versi 2.5.0:

git branch -d `git branch --merged`
drautb
sumber
16
Ini dapat menghapus mastercabang btw!
Wazery
4
Benar. Saya hanya menggunakannya ketika saya yakin saya aktif master.
drautb
11
git branch -d $(git branch --merged | grep -v master)
alexg
1
Ini berbahaya jika Anda memiliki aliran, bayangkan Anda memiliki master <- stage <- dev. Masih solusi termudah imo
Joseph Briggs
14

Anda dapat menambahkan komit ke opsi --merged. Dengan cara ini Anda dapat memastikan hanya untuk menghapus cabang yang digabungkan ke dalam yaitu asal / master

Perintah berikut akan menghapus cabang gabungan dari asal Anda.

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

Anda dapat menguji cabang mana yang akan dihapus menggantikan asal git push --delete dengan gema

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
Jörn Reimerdes
sumber
2
Saya suka opsi tes
iwein
12

Saya menggunakan skrip Ruby berikut untuk menghapus cabang lokal dan jarak jauh saya yang sudah bergabung. Jika saya melakukannya untuk repositori dengan beberapa remote dan hanya ingin menghapus dari satu, saya hanya menambahkan pernyataan pilih ke daftar remote untuk hanya mendapatkan remote yang saya inginkan.

#!/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
mmrobin
sumber
Keberatan jika saya mencuri berita gembira ini untuk perpustakaan git helper? github.com/yupiq/git-branch-util
logan
1
Pergi untuk itu, saya tidak akan menaruhnya di sini jika saya peduli orang menggunakan kembali kode dalam beberapa cara
mmrobins
@ mmrobins Anda memiliki ekstra \/di awal pernyataan tolak untuk remote_branchessaluran tersebut. Apakah itu salah ketik atau apakah ada gunanya?
Jawwad
@ mmrobins, oh sudahlah, saya melihat b.split(/\//)garis sekarang
Jawwad
Jika Anda ingin melakukan ini pada dasarnya tetapi melalui vanilla bash daripada ruby: stackoverflow.com/a/37999948/430128
Raman
11

Cara menghapus cabang yang digabungkan di konsol PowerShell

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

Jika Anda ingin mengecualikan master atau nama cabang lainnya, Anda dapat mem-pipe dengan PowerShell Select-String seperti ini dan meneruskan hasilnya ke git branch -d:

git branch -d $(git branch --merged | Select-String -NotMatch "master" | %{$_.ToString().Trim()})
Konstantin Tarkus
sumber
1
Jawaban yang lebih tinggi menyarankan master penyaringan atau cabang lainnya. Bagi mereka yang ingin melakukannya di PowerShell: git branch --merged | findstr / v "master" | % {git branch -d $ _. trim ()}
tredzko
@ tredzko Poin bagus. FTR jawaban yang lebih tinggi adalah stackoverflow.com/questions/6127328/… - Anda dapat memposting ulang komentar Anda dengan tautan itu dan saya kemudian akan menghapusnya
Ruben Bartelink
itu juga mencoba untuk menghapus * master:)
iesen
9

Jawaban kuboon tidak terjawab menghapus cabang yang memiliki kata master dalam nama cabang. Berikut ini meningkatkan jawabannya:

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

Tentu saja, itu tidak menghapus cabang "master" itu sendiri :)

Paras
sumber
8

Tidak ada perintah di Git yang akan melakukan ini untuk Anda secara otomatis. Tetapi Anda dapat menulis skrip yang menggunakan perintah Git untuk memberikan apa yang Anda butuhkan. Ini bisa dilakukan dalam banyak cara tergantung pada model percabangan apa yang Anda gunakan.

Jika Anda perlu tahu apakah cabang telah digabungkan menjadi master, perintah berikut tidak akan menghasilkan output jika myTopicBranch telah digabung (yaitu Anda dapat menghapusnya)

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

Anda bisa menggunakan perintah cabang Git dan mem-parsing semua cabang di Bash dan lakukan forperulangan di semua cabang. Dalam loop ini Anda memeriksa dengan perintah di atas apakah Anda dapat menghapus cabang atau tidak.

ralphtheninja
sumber
7

Catatan : Saya tidak senang dengan jawaban sebelumnya, (tidak bekerja pada semua sistem, tidak bekerja pada jarak jauh, tidak menentukan cabang --merged, tidak memfilter dengan tepat). Jadi, saya tambahkan jawaban saya sendiri.

Ada dua kasus utama:

Lokal

Anda ingin menghapus cabang lokal yang sudah bergabung ke cabang lokal lain . Selama penghapusan, Anda ingin menyimpan beberapa cabang penting, seperti master, mengembangkan, dll.

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

Catatan :

  • git branch output --format ".." adalah untuk menghapus spasi putih dan memungkinkan pencocokan grep yang tepat
  • grep -Edigunakan sebagai ganti egrep , sehingga berfungsi juga dalam sistem tanpa egrep (yaitu: git for windows).
  • grep -E -v '^master$|^feature/develop$' adalah untuk menentukan cabang lokal yang tidak ingin saya hapus
  • xargs -n 1 git branch -d: melakukan penghapusan cabang lokal (itu tidak akan bekerja untuk yang jauh)
  • tentu saja Anda mendapatkan kesalahan jika Anda mencoba menghapus cabang yang saat ini check-out. Jadi, saya sarankan untuk beralih ke master sebelumnya.

Terpencil

Anda ingin menghapus cabang jarak jauh yang sudah bergabung ke cabang jarak jauh lain . Selama penghapusan, Anda ingin menyimpan beberapa cabang penting, seperti KEPALA, master, rilis, dll.

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

Catatan :

  • untuk jarak jauh, kami menggunakan -ropsi dan memberikan nama cabang lengkap :origin/master
  • grep -E -v '^*HEAD$|^*/master$|^*release' adalah untuk mencocokkan cabang jarak jauh yang tidak ingin kita hapus.
  • cut -d/ -f2- : hapus awalan 'asal /' yang tidak dibutuhkan yang kalau tidak dicetak oleh git branch perintah.
  • xargs -n 1 git push --delete origin : melakukan penghapusan cabang jarak jauh.
psuzzi
sumber
7

Jika Anda menggunakan Windows, Anda dapat menggunakan Windows Powershell atau Powershell 7 dengan Out-GridView untuk memiliki daftar cabang yang bagus dan memilih dengan mouse mana yang ingin Anda hapus:

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

masukkan deskripsi gambar di sini setelah mengklik OK Powershell akan meneruskan nama cabang ini ke git branch -dperintah dan menghapusnya masukkan deskripsi gambar di sini

Mariusz Pawelski
sumber
6

Anda bisa menggunakan git-del-br alat .

git-del-br -a

Anda dapat menginstalnya pipmenggunakan

pip install git-del-br

PS: Saya pembuat alat. Ada saran / umpan balik.

tusharmakkar08
sumber
1
@ stackoverflow.com/users/100297/martijn-pieters : Mengapa jawaban ini dihapus dan diturunkan?
tusharmakkar08
1
Jawaban dan alat Anda tidak berfungsi. Saya menghabiskan beberapa jam untuk itu. Tidak ada.
SpoiledTechie.com
@ SpoiledTechie.com: Bisakah Anda memberi tahu saya masalah apa yang Anda hadapi sebenarnya? Saya menggunakannya secara teratur.
tusharmakkar08
Saya dapat membagikan tangkapan layar jika Anda ingin membuatnya offline? manja teknik di google mail itu. :)
SpoiledTechie.com
5

Jika Anda ingin menghapus semua cabang lokal yang sudah digabung ke cabang tempat Anda saat ini, maka saya telah membuat perintah aman untuk melakukannya, berdasarkan jawaban sebelumnya:

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

Perintah ini tidak akan memengaruhi cabang Anda saat ini atau cabang master Anda. Ini juga akan memberi tahu Anda apa yang dilakukannya sebelum melakukannya, menggunakan flag -t xargs.

chrismendis
sumber
5

Versi terbaru dari jawaban Adam yang diperbarui :

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

Juga, lihat jawaban ini untuk tips praktis tentang melarikan diri alias kompleks.

Eliot
sumber
5

Saya menggunakan skema penamaan esque git-flow, jadi ini bekerja sangat aman untuk saya:

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

Ini pada dasarnya mencari komit gabungan yang dimulai dengan string fix/atau feature/.

Chad M
sumber
4

Coba perintah berikut:

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

Dengan menggunakan git rev-parseakan mendapatkan nama cabang saat ini untuk mengecualikannya. Jika Anda mendapatkan kesalahan, itu berarti tidak ada cabang lokal untuk dihapus.

Untuk melakukan hal yang sama dengan cabang jarak jauh (ubah origindengan nama jarak jauh Anda), coba:

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

Jika Anda memiliki beberapa remote, tambahkan grep origin |sebelumnya cutuntuk memfilter hanyaorigin .

Jika perintah di atas gagal, coba hapus cabang pelacakan jarak jauh yang digabungkan terlebih dahulu:

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

Kemudian git fetchremote lagi dan gunakan git push -vdperintah sebelumnya lagi.

Jika Anda sering menggunakannya, pertimbangkan untuk menambahkan alias ke blog Anda ~/.gitconfig file .

Jika Anda secara tidak sengaja menghapus beberapa cabang, gunakan git refloguntuk menemukan komit yang hilang.

kenorb
sumber
4

Berdasarkan beberapa jawaban ini saya membuat skrip Bash saya sendiri untuk melakukannya juga !

Menggunakan git branch --mergeddan git branch -dmenghapus cabang yang telah digabungkan dan meminta Anda untuk masing-masing cabang sebelum menghapus.

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
}
earlonrails
sumber
4

Kueri di bawah ini berfungsi untuk saya

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

dan ini akan menyaring cabang apa pun yang diberikan dalam pipa grep.

Bekerja dengan baik melalui http clone, tetapi tidak begitu baik untuk koneksi ssh.

pengguna1460965
sumber
4

Pada 2018.07

Tambahkan ini ke [alias]bagian Anda ~/.gitconfig:

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

Sekarang Anda bisa menelepon git sweepuntuk melakukan pembersihan yang diperlukan.

Sorin
sumber
Bagi saya, memanggil git sweep hanya mendaftar cabang-cabang yang harus dibersihkan, tetapi tidak menghapusnya
Victor Moraes
4

Pada Windows dengan git bash terpasang egrep -v tidak akan berfungsi

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

di mana grep -E -vsetara denganegrep -v

Gunakan -duntuk menghapus cabang yang sudah digabung atau -Duntuk menghapus cabang yang tidak dimerger

DevWL
sumber
egrep -v bekerja untuk saya. Saya menggunakan gitbash dari installer gitextensions
Joe Phillips
4

Saya telah menggunakan metode berikut untuk menghapus cabang lokal DAN remote dalam satu cmd.

Saya memiliki yang berikut ini di bashrcfile saya :

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
}

sumber asli

Ini tidak menghapus cabang master, tetapi menghapus cabang lokal DAN jarak jauh yang digabungkan . Setelah Anda memiliki ini di file rc Anda, jalankan saja rmb, Anda akan ditampilkan daftar cabang gabungan yang akan dibersihkan dan meminta konfirmasi tentang tindakan tersebut. Anda dapat memodifikasi kode untuk tidak meminta konfirmasi juga, tetapi mungkin baik untuk menyimpannya.

Prashant
sumber
3

Tulis skrip di mana Git memeriksa semua cabang yang telah digabungkan untuk dikuasai.

Lalu lakukan git checkout master .

Akhirnya, hapus cabang yang digabungkan.

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
Komu
sumber
3

Solusi yang diterima cukup bagus, tetapi memiliki satu masalah yang juga menghapus cabang lokal yang belum digabungkan menjadi remote.

Jika Anda melihat outputnya Anda akan melihat sesuatu seperti

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

Cabang bladanissue_248 cabang lokal yang akan dihapus secara diam-diam.

Tapi Anda juga bisa melihat kata itu [gone] , yang menunjukkan cabang yang telah didorong ke jarak jauh (yang sekarang hilang) dan dengan demikian menunjukkan cabang dapat dihapus.

Dengan demikian, jawaban asli dapat diubah menjadi (dibagi menjadi multiline untuk panjang garis yang lebih pendek)

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

untuk melindungi cabang yang belum digabung. Juga grepping bagi master untuk melindunginya, tidak diperlukan, karena ini memiliki remote pada awalnya dan tidak muncul sebagai hilang.

Heiko Rupp
sumber
3

Bagi saya git branch --mergedtidak menunjukkan cabang yang digabungkan melalui GitHub PR. Saya tidak yakin alasannya, tetapi saya menggunakan baris berikut untuk menghapus semua cabang lokal yang tidak memiliki cabang pelacakan jarak jauh :

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

Penjelasan:

  • git branch --format "%(refname:short)" memberikan daftar cabang lokal
  • git branch -r | grep -v HEAD | cut -d/ -f2- memberikan daftar cabang jauh, memfilter HEAD
  • diff <(...) <(...) memberikan perbedaan keluaran dari dua perintah di dalam tanda kurung
  • grep '<' memfilter cabang yang ada di daftar pertama, tetapi tidak di yang kedua
  • cut -c 3- memberikan garis mulai dari karakter ke-3, sehingga menghilangkan awalan <
  • xargs git branch -Ddieksekusi git branch -Dterhadap setiap nama cabang

Atau, Anda dapat menghindari grep -v '<'seperti ini:

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
folex
sumber