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.


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\..*'`

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

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\*`

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.*'`

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 .


28

Menggunakan

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

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.


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-*'`

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.


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 .


6

Terus "kembangkan" dan hapus semua yang lain di lokal

    git branch | grep -v "develop" | xargs git branch -D 

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!


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


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.

3

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


2

itu berfungsi dengan baik untuk saya:

git branch | xargs git branch -d

git branch | xargs git branch -D

hapus semua cabang lokal


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


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.


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.


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.


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.


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.


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


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!


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



-4

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

rm .git/refs/heads/3.2.*


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.