Bisakah Anda menghapus beberapa cabang dalam satu perintah dengan Git?

355

Saya ingin membersihkan repositori lokal saya, yang memiliki satu ton cabang tua: misalnya 3.2, 3.2.1, 3.2.2, dll

Saya berharap cara licik untuk menghapus banyak dari mereka sekaligus. Karena mereka kebanyakan mengikuti konvensi dot release, saya pikir mungkin ada jalan pintas untuk mengatakan:

git branch -D 3.2.*

dan bunuh semua cabang 3.2.x.

Saya mencoba perintah itu dan itu, tentu saja, tidak berhasil.

Doug
sumber
11
git branch -D $(git branch | grep 3.2*)- ini bekerja untuk saya. Ini menghapus cabang yang namanya dimulai dengan "3.2". grep- pencocokan pola dalam output ( git branchdalam hal ini). $()- Berarti mengeksekusi dan menempatkan hasilnya. |- rantai.
Eduard
4
Layak dicatat bagi mereka yang tidak tahu, itu -Dadalah penghapusan kekuatan , harus digunakan -ddalam banyak kasus untuk lebih aman terlebih dahulu.
redfox05

Jawaban:

363

Tidak dengan sintaks itu. Tetapi Anda dapat melakukannya seperti ini:

git branch -D 3.2 3.2.1 3.2.2

Pada dasarnya, cabang git akan menghapus banyak cabang untuk Anda dengan satu permintaan. Sayangnya itu tidak menyelesaikan nama cabang. Meskipun, dalam bash, Anda dapat melakukan:

git branch -D `git branch | grep -E '^3\.2\..*'`
Slebetman
sumber
2
Penyelesaian git branch -D/-dbekerja dengan baik untuk saya. Mungkin ingin memperbarui milik Anda (mungkin dari direktori contrib git.git terbaru).
Cascabel
19
Alih-alih git branch | ...Anda bisa menggunakan $(git for-each-ref --format='%(refname:short)' refs/heads/3.*). Ini lebih lama, saya tahu, tetapi dijamin menjadi output yang sesuai, sementara git branchmemiliki output yang cukup dengan hal-hal seperti *dan ->(untuk symrefs) yang dapat mengacaukan Anda dalam skrip / one-liners.
Cascabel
3
Mungkin saya satu-satunya dengan masalah ini, tetapi saya grepselalu menyertakan bendera --color=always- git branch -Dmelemparkan error: branch 'my_branch' not found.sampai saya berlari tanpa bendera warna.
eebbesen
@eebbesen Apakah Anda menonaktifkannya secara global? Saya mengalami masalah yang sama ketika menjalankangit branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
qmmr
2
Dengan ekspansi brace, Anda dapat menulis git branch -D 3.2{,.1,.2}untuk menghapus ketiga cabang gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck
147

Nah, dalam kasus terburuk, Anda bisa menggunakan:

git branch | grep '3\.2' | xargs git branch -d
Carl Norum
sumber
22
Ini cukup banyak metode yang sempurna untuk siapa saja yang menggunakan notasi awalan standar untuk nama cabang (mis. "Fix / ..." atau "feature / ...").
Haz
4
Sederhana dan efisien! Saya akan merekomendasikan meskipun berjalan terlebih dahulu tanpa | xargs git branch -dbagian untuk memeriksa apa yang sebenarnya akan dihapus.
mathielo
Dianjurkan untuk tidak grepoutput git branch, seperti yang dimaksudkan untuk membaca, bukan penguraian. Bisa berubah sewaktu-waktu. gunakan for-each-refbersama - sama dengan --formatparams, seperti yang disarankan dalam jawaban lain, dan kemudian gabungkan dengan saran dalam jawaban ini.
redfox05
138
git branch  | cut -c3- | egrep "^3.2" | xargs git branch -D
  ^                ^                ^         ^ 
  |                |                |         |--- create arguments
  |                |                |              from standard input
  |                |                |
  |                |                |---your regexp 
  |                |
  |                |--- skip asterisk 
  |--- list all 
       local
       branches

EDIT:

Versi yang lebih aman (disarankan oleh Jakub Narębski dan Jefromi), karena keluaran git branch tidak dimaksudkan untuk digunakan dalam skrip:

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

... atau xargs-free:

git branch -D `git for-each-ref --format="%(refname:short)" refs/heads/3.2\*`
gawi
sumber
14
Jangan gunakan git branchoutput untuk skrip. Gunakan git for-each-ref.
Jakub Narębski
1
Untuk menghapus tag dengan simbol @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt
Memiliki kesalahan ketik. Seharusnya "/3.2/*" bukan "/3.2*". Selain itu, tampaknya Anda menyalin jawaban yang dilekatkan ke jawaban Anda.
Max MacLeod
Tidak ada salah ketik di sini. Dari halaman manual:If one or more patterns are given, only refs are shown that match against at least one pattern, either using fnmatch(3) or literally, in the latter case matching completely or from the beginning up to a slash
gawi
1
Layak dicatat bagi mereka yang tidak tahu, itu -Dadalah penghapusan kekuatan , harus digunakan -ddalam banyak kasus untuk lebih aman terlebih dahulu.
redfox05
115

Anda dapat menggunakan cabang git - daftar untuk mendaftar cabang yang memenuhi syarat, dan menggunakan cabang git -D / -d untuk menghapus cabang yang memenuhi syarat.

Contoh satu liner:

git branch -d `git branch --list '3.2.*'`
50shadesofbae
sumber
Ketika saya mencoba ini, saya mendapatkan banyak pesan kesalahan seperti error: branch 'package.json' not found.. Tampaknya * diperluas terlalu dini, dan mencoba untuk menghapus cabang yang sesuai dengan nama setiap file dan direktori.
Antimony
Ini bekerja dengan baik! Saya mengalami masalah menggunakan ini sebagai alias dengan gitconfigmeskipun ...
whoaniac
6
Jawaban ini harus lebih tinggi dalam daftar, super bersih, berfungsi, tidak ada grep
jemiloii
1
Bagus bahwa yang ini mudah untuk diuji pertama dengan hanya mengeluarkangit branch --list '3.2.*'
Will
3
Pada windowsgit branch -d (git branch --list '3.2.*').trim()
Mattias Josefsson
38

Baru-baru ini, saya mencari solusi untuk masalah yang sama, akhirnya saya menemukan satu jawaban dan itu bekerja dengan sangat baik:

  1. Buka terminal, atau yang setara.
  2. Ketik cabang git | grep "pattern" untuk pratinjau cabang yang akan dihapus.
  3. Ketik cabang git | grep "pola" | cabang xargs git -D

Solusi ini luar biasa dan jika Anda ingin penjelasan lengkap dari setiap perintah dan cara kerjanya, diberikan di sini .

KJ Gor
sumber
28

Menggunakan

git for-each-ref --format='%(refname:short)' 'refs/heads/3.2.*' |
   xargs git branch -D
Jakub Narębski
sumber
7
tip kecil adalah bahwa jika Anda menghapus bagian terakhir dari perintah "| xargs git branch -D" maka itu hanya akan menampilkan cabang yang cocok. Jadi, Anda dapat melihat pratinjau cabang yang akan dihapus
Max MacLeod
1
Saya juga menambahkan alias untuk menyederhanakan ini: alias grefs='git for-each-ref --format="%(refname:short)"'jadi saya bisa melakukannyagrefs | grep 'regexpattern' | xargs git branch -D
angularsen
Menyukainya. Bagus dan sederhana!
Bhargav Ponnapalli
15

Mungkin Anda akan menemukan ini berguna:

Jika Anda ingin menghapus semua cabang yang bukan misalnya 'master', 'foo' dan 'bar'

git branch -D `git branch | grep -vE 'master|foo|bar'`

grep -v 'something' adalah korek api dengan inversi.

Adi
sumber
Saya pribadi suka -Dopsi dibandingkan dengan jawaban lain. Terima kasih atas jawabannya di sini @Adi. Solusi bekerja untuk saya.
AMIC MING
9

Saya menempatkan inisial dan tanda hubung saya (at-) sebagai tiga karakter pertama dari nama cabang untuk alasan yang tepat ini:

git branch -D `git branch --list 'at-*'`
Alan Tweedie
sumber
Semua jawaban pada dasarnya mengatakan ini, ini adalah yang paling sederhana.
tfantina
7

Jika Anda tidak dibatasi untuk menggunakan prompt perintah git, maka Anda selalu dapat menjalankan git guidan menggunakan item menu Branch-> Delete. Pilih semua cabang yang ingin Anda hapus dan biarkan rip.

Efpophis
sumber
ini hanya memungkinkan Anda menghapus cabang lokal
Stealth Rabbi
7

Solusi Powershell:

Jika Anda menjalankan windows, Anda dapat menggunakan PowerShell untuk menghapus beberapa cabang sekaligus ...

git branch -D ((git branch | Select-String -Pattern '^\s*3\.2\..*') | foreach{$_.ToString().Trim()})
//this will remove all branches starting with 3.2.

git branch -D ((git branch | Select-String -Pattern 'feature-*') | foreach{$_.ToString().Trim()})
// this will delete all branches that contains the word "feature-" as a substring.

Anda juga dapat menyesuaikan bagaimana pencocokan pola harus bekerja menggunakan perintah Select-String Powershell. Lihatlah dokumen PowerShell .

Imtiaz Shakil Siddique
sumber
6

Terus "kembangkan" dan hapus semua yang lain di lokal

    git branch | grep -v "develop" | xargs git branch -D 
Daniel
sumber
5

Saya membuat fungsi kecil yang mungkin berguna berdasarkan jawaban yang diberikan oleh @gawi (di atas).

removeBranchesWithPrefix() {
  git for-each-ref --format="%(refname:short)" refs/heads/$1\* | xargs git branch -d
}

Tambahkan itu ke Anda .bash_profiledan mulai ulang terminal Anda. Maka Anda dapat menelepon dari command-line seperti ini:

removeBranchesWithPrefix somePrefix

Catatan

Saat ini saya sudah menyiapkan untuk penghapusan lunak, yang berarti tidak akan menghapus cabang kecuali mereka sudah bergabung. Jika Anda suka hidup di tepi, ubah -dke -Ddan itu akan menghapus semuanya dengan awalan!

Logan
sumber
5

Jika Anda benar-benar perlu membersihkan semua cabang Anda, cobalah

git branch -d $(git branch)

Ini akan menghapus semua cabang gabungan lokal Anda kecuali cabang yang sedang Anda periksa.

Ini cara yang baik untuk membuat kebersihan lokal Anda

Yulin
sumber
Ini bekerja cukup baik untuk saya. Itu meninggalkan dua cabang kecuali yang saya adalah salah satu yang saya kemudian dihapus dengan menggunakan perintah yang sama tetapi menggunakan huruf kapital "-D" bukannya "-d". Saya mendapat beberapa kesalahan tentang git tidak menemukan file tetapi cabang dihapus.
Lurifaxel
3

Anda mungkin menyukai item kecil ini ... Ini menarik daftar dan meminta konfirmasi untuk setiap item sebelum akhirnya menghapus semua pilihan ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "remove branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done`

Gunakan -D untuk memaksa penghapusan (seperti biasa).

Agar mudah dibaca, berikut ini adalah garis putus-putus ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* |
    while read -r line; do 
        read -p "remove branch: $line (y/N)?" answer </dev/tty;
        case "$answer" in y|Y) echo "$line";; 
        esac; 
    done`

di sini adalah pendekatan xargs ...

git for-each-ref --format="%(refname:short)" refs/heads/\* |
while read -r line; do 
    read -p "remove branch: $line (y/N)?" answer </dev/tty;
    case "$answer" in 
        y|Y) echo "$line";; 
    esac; 
done | xargs git branch -D

akhirnya, saya suka memiliki ini di .bashrc saya

alias gitselect='git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "select branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done'

Dengan begitu aku bisa bilang begitu

gitSelect | xargs git branch -D.
Kekacauan keinginan
sumber
3

Untuk jiwa murni yang menggunakan PowerShell di sini skrip kecil git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })

codevision
sumber
2

itu berfungsi dengan baik untuk saya:

git branch | xargs git branch -d

git branch | xargs git branch -D

hapus semua cabang lokal

velastiqui
sumber
2

Gunakan perintah berikut untuk menghapus semua cabang (cabang yang dicentang tidak akan dihapus).

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

Sunting: Saya menggunakan Mac Os

ILYAS_Kerbal
sumber
0

Jika Anda menggunakan windows, Anda dapat menggunakan PowerShell untuk melakukan ini:

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

ganti feature/*dengan pola yang Anda suka.

Mo Valipour
sumber
6
grep adalah cmdlet yang tidak dikenali untuk saya ... jadi saya sudah berubah untuk cabang git ini | where {$ _. Trim (). StartsWith ("bug")} | % {git branch -D $ _. Trim ()} dan berhasil!
Alex
0

Anda dapat menggunakan git guiuntuk menghapus beberapa cabang sekaligus. Dari Command Prompt / Bash -> git gui-> Remote -> Hapus cabang ... -> pilih cabang jarak jauh yang ingin Anda hapus -> Hapus.

Terry Truong
sumber
0

Saya baru saja membersihkan satu set cabang lokal / terpencil yang sudah usang hari ini.

Di bawah ini adalah bagaimana saya melakukannya:

1. daftar semua nama cabang ke file teks:

git branch -a >> BranchNames.txt

2. tambahkan cabang yang ingin saya hapus ke perintah "git branch -D -r":

cabang git -D -r asal / dirA / branch01 asal / dirB / branch02 asal / dirC / branch03 (... tambahkan nama cabang apa pun)

3. jalankan cmd

Dan yang ini bekerja jauh lebih cepat dan dapat diandalkan daripada " git push origin --delete ".

Ini mungkin bukan cara yang paling cerdas seperti yang tercantum dalam jawaban lain, tetapi yang ini cukup mudah, dan mudah digunakan.

RainCast
sumber
0

Jika Anda telah menginstal Git GUI, yang merupakan add-on default untuk Windows, maka itu yang paling sederhana. Anda dapat menggunakan ctrl untuk memilih beberapa cabang dan menghapusnya dengan satu klik.

peiz
sumber
0

Jika Anda menggunakan Kerang Ikan, Anda dapat memanfaatkan stringfungsinya :

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

Ini tidak jauh berbeda dari opsi Powershell dalam beberapa jawaban lainnya.

mdiin
sumber
0

Jika Anda memiliki semua cabang untuk dihapus dalam file teks (branch-to-del.txt) (satu cabang per baris), maka Anda bisa melakukan ini untuk menghapus semua cabang tersebut dari jarak jauh (asal): xargs -a branches-to-del.txt git push --delete origin

code4kix
sumber
0

Untuk menghapus beberapa cabang berdasarkan pola yang ditentukan lakukan hal berikut:

Buka terminal, atau setara dan ketik perintah berikut:

git branch | grep "<pattern>" (preview of the branches based on pattern)

git branch | grep "<pattern>" | xargs git branch -D (replace the <pattern> with a regular expression to match your branch names)

Hapus semua cabang 3.2.x, Anda perlu mengetik

git branch | grep "3.2" | xargs git branch -D

Itu saja!

Kamu baik untuk pergi!

Ankit Jindal
sumber
-1

Seperti dalam Git, semua cabang bukan apa-apa dengan merujuk pada repo git, mengapa Anda tidak menghapus saja cabang yang dituju .git/refdan kemudian jika ada sesuatu yang tidak menarik di repositori akan secara otomatis menjadi sampah yang dikumpulkan sehingga Anda tidak perlu repot.

Debajit
sumber
-3

git branch -D <branchName>

Aakash Pahuja
sumber
-4

Anda dapat menghapus semua cabang dengan menghapus semua referensi yang tidak perlu:

rm .git/refs/heads/3.2.*

Artur Owczarek
sumber
2
Turun karena dua alasan: 1. ia menggunakan detail implementasi (fakta bahwa versi Git saat ini menyimpan cabang sebagai file dalam direktori tertentu). Ini dapat berubah di versi mendatang sehingga jawaban tidak valid. 2. Tidak berfungsi jika repositori terletak di direktori yang terpisah .
aksioma
Juga, ini menghasilkan hasil yang sangat tidak terduga jika Anda menjalankan ini pada repositori yang dikemas ( git gc). Jangan lakukan itu.
Matthieu Moy