Cara memangkas cabang pelacakan lokal yang tidak ada pada jarak jauh lagi

770

Dengan git remote prune originsaya dapat menghapus cabang lokal yang tidak lagi di remote.

Tapi saya juga ingin menghapus cabang lokal yang dibuat dari cabang-cabang terpencil itu (cek jika tidak dihapus akan lebih baik).

Bagaimana saya bisa melakukan ini?

Alex
sumber
8
Kemungkinan duplikat Hapus cabang lokal tidak lagi di remote
kolen
1
One-liner, cross platform, tidak terlihat seperti kucing tidur di keyboard Anda: npx git-removed-branches(lari kering) atau npx git-removed-branches --prune(nyata). Anda harus sudah menginstal node.js. Lihat jawaban di bawah untuk detailnya.
Cristian Diaconescu

Jawaban:

892

Setelah pemangkasan, Anda bisa mendapatkan daftar cabang jarak jauh git branch -r. Daftar cabang dengan cabang pelacakan jarak jauh mereka dapat diambil dengan git branch -vv. Jadi, menggunakan kedua daftar ini, Anda dapat menemukan cabang pelacakan jarak jauh yang tidak ada dalam daftar remote.

Baris ini harus melakukan trik (mengharuskan bashatau zsh, tidak akan bekerja dengan shell Bourne standar):

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

String ini mendapatkan daftar cabang jarak jauh dan meneruskannya egrepmelalui input standar. Dan memfilter cabang yang memiliki cabang pelacakan jarak jauh (menggunakan git branch -vvdan memfilter untuk yang memiliki origin) kemudian mendapatkan kolom pertama dari output yang akan menjadi nama cabang. Akhirnya meneruskan semua nama cabang ke perintah hapus cabang.

Karena menggunakan -dopsi, itu tidak akan menghapus cabang yang belum digabung ke cabang yang Anda aktifkan saat Anda menjalankan perintah ini.

Ingat juga bahwa Anda harus menjalankannya git fetch --prune terlebih dahulu , jika tidak, git branch -rmasih akan melihat cabang jarak jauh.

Schleis
sumber
12
Ini bekerja dengan baik untuk saya. Entah bagaimana, git fetch -ptidak selalu cukup?
Stefan Hendriks
16
Sayangnya ini tidak berfungsi di Git Bash di Windows. sh.exe": cannot make pipe for process substitution: Function not implemented sh.exe": egrep -v -f /dev/fd/0: No such file or directory fatal: branch name required Ada ide?
Ludder
37
Untuk menambahkannya sebagai alias:alias git-remove-untracked='git fetch --prune && git branch -r | awk "{print \$1}" | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk "{print \$1}" | xargs git branch -d'
bryant1410
126
Apakah ada perintah yang diusulkan untuk rilis git masa depan yang akan melakukan ini? Perintah ini sepertinya kucing saya sudah ada di laptop saya
Bron Davies
5
menggunakan git branch -Dpada akhir perintah bekerja lebih baik untuk kita, karena kita cenderung menekan komit pada penggabungan, yang membuat kita The branch x is not fully mergedkesalahan saat menjalankan -d.
Mateus Gondim
430

Jika Anda ingin menghapus semua cabang lokal yang sudah digabung menjadi master, Anda dapat menggunakan perintah berikut:

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

Info lebih lanjut .

jackocnr
sumber
4
Bekerja dengan sempurna, saya pikir! Adakah yang bisa menjelaskan jika jawaban ini melakukan sesuatu yang berbeda dari jawaban yang diterima?
Andrew
11
Perbaikan kecil: gunakan xargs -r git branch -dagar tidak ada yang berjalan jika tidak ada cabang yang dihapus. Perhatikan bahwa -rbendera mungkin tidak tersedia di mana
Jacob Wang
8
Karena grep mungkin tidak cocok karena warna git:git branch --merged master --no-color | grep -v '^* master$' | xargs -n1 -r git branch -d
Mike D
5
@NickRes melihat ketika Anda bertanya dengan sangat baik, git branch --merged masterdaftar cabang yang digabung menjadi master, maka bagian grep tengah mengecualikan master itu sendiri (kami tidak ingin menghapus master!), Dan bagian xargs terakhir dijalankan git branch -d(hapus cabang) pada masing-masing hasil. Atau Anda bisa membaca tautan More info yang disediakan dalam jawaban;)
jackocnr
14
Perbaikan: git branch --merged master | egrep -v '^\s*\*?\s*master$' | xargs git branch -d. Output dari git v2.10.1 akan menampilkan "* master" saat master di-check out. Saya menyingkirkan master baik dengan atau tanpa tanda bintang.
Esteban
162

Di tengah informasi yang disajikan oleh git help fetch, ada item kecil ini:

 -p, --prune
        After fetching, remove any remote-tracking branches which no longer exist on the remote.

Jadi, mungkin, git fetch -papa yang Anda cari?

EDIT: Ok, bagi mereka yang masih memperdebatkan jawaban ini 3 tahun setelah fakta, berikut adalah sedikit informasi tentang mengapa saya mempresentasikan jawaban ini ...

Pertama, OP mengatakan mereka ingin "menghapus juga cabang-cabang lokal yang dibuat dari cabang-cabang terpencil [yang tidak ada lagi di remote]". Ini tidak mungkin secara ambigu dalam git. Ini sebuah contoh.

Katakanlah saya memiliki repo di server pusat, dan memiliki dua cabang, dipanggil Adan B. Jika saya mengkloning repo itu ke sistem lokal saya, klon saya akan memiliki referensi lokal (belum cabang sebenarnya) yang dipanggil origin/Adan origin/B. Sekarang katakanlah saya melakukan hal berikut:

git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C <some hash>

Fakta terkait di sini adalah bahwa saya karena suatu alasan memilih untuk membuat cabang pada repo lokal saya yang memiliki nama yang berbeda dari asalnya, dan saya juga memiliki cabang lokal yang (belum) ada pada repo asal.

Sekarang katakanlah saya menghapus kedua Adan Bcabang pada repo jarak jauh dan memperbarui repo lokal saya ( git fetchdari beberapa bentuk), yang menyebabkan referensi lokal saya origin/Adan origin/Bmenghilang. Sekarang, repo lokal saya memiliki tiga cabang masih, A, Z, dan C. Tak satu pun dari ini memiliki cabang yang sesuai pada repo jarak jauh. Dua dari mereka "diciptakan dari ... cabang-cabang terpencil", tetapi bahkan jika saya tahu bahwa dulu ada cabang yang disebut Basal, saya tidak punya cara untuk mengetahui bahwa Zitu diciptakan dariB, karena diganti namanya dalam proses, mungkin karena alasan yang baik. Jadi, sungguh, tanpa beberapa proses eksternal merekam metadata asal cabang, atau manusia yang mengetahui sejarah, tidak mungkin untuk mengatakan yang mana dari tiga cabang, jika ada, OP menargetkan untuk dihapus. Tanpa beberapa informasi eksternal yang gittidak secara otomatis menjaga untuk Anda, git fetch -padalah sedekat yang Anda bisa dapatkan, dan metode otomatis apa pun untuk benar-benar mencoba apa yang diminta OP berisiko mengambil terlalu banyak cabang, atau melewatkan beberapa yang OP akan sebaliknya ingin dihapus.

Ada skenario lain, juga, seperti jika saya membuat tiga cabang terpisah origin/Auntuk menguji tiga pendekatan berbeda untuk sesuatu, dan kemudian origin/Ahilang. Sekarang saya memiliki tiga cabang, yang jelas tidak semuanya cocok dengan nama-bijaksana, tetapi mereka diciptakan dari origin/A, sehingga interpretasi literal dari pertanyaan OPs akan membutuhkan penghapusan ketiganya. Namun, itu mungkin tidak diinginkan, jika Anda bahkan dapat menemukan cara yang dapat diandalkan untuk mencocokkannya ...

Twalberg
sumber
108
Ini tidak menghapus cabang lokal, hanya pointer jarak jauh ke cabang
Jaap
4
Ini hanya menghapus cabang lokal ini, yang tidak ada di remote DAN Anda tidak pernah melakukan checkout pada mereka.
Jarek Jakubowski
15
Anda harus membaca pertanyaan lebih hati-hati seperti catatan Jaap. Orang-orang yang memberikan suara untuk jawaban ini juga harus membaca apa sebenarnya pertanyaan itu.
Søren Boisen
4
Ya, ini sebenarnya yang ingin saya lakukan! @ SørenBoisen Saya harap dalam dua tahun terakhir Anda punya waktu untuk meninjau kembali pendapat Anda itu ... Jika konten yang diposkan di SO harus selalu hanya terkait dengan apa yang kadang-kadang ditanyakan oleh OP, kami akan menghapus banyak informasi. Tolong jangan berasumsi untuk menginstruksikan orang bagaimana mereka dapat menggunakan situs ini, selain dari pedoman resmi, dan mereka jelas tidak mencegah jawaban ortogonal namun bermanfaat.
Félix Gagnon-Grenier
6
@ FélixGagnon-Grenier Inilah masalah saya dengan jawaban ini: 1) Pertanyaannya sangat jelas, OP jelas tidak bingung. 2) Jawaban ini tidak menyebutkan bahwa ia tidak menjawab pertanyaan! 3) Pertanyaannya sudah menyatakan cara untuk memangkas cabang pelacakan jarak jauh yang tidak ada lagi, sehingga menambah nilai nol.
Søren Boisen
117

Ini akan menghapus cabang lokal tempat cabang pelacakan jarak jauh telah dipangkas. (Pastikan Anda berada di mastercabang!)

git checkout master
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d

Detail:

  • git branch -vv menampilkan "pergi" untuk cabang-cabang lokal bahwa remote telah dipangkas.

    mybranch abc1234 [origin/mybranch: gone] commit comments
    
  • -dakan memeriksa apakah telah digabung ( -Dakan menghapusnya terlepas)

    error: The branch 'mybranch' is not fully merged.
    
wisbucky
sumber
16
Anda bahkan dapat membuat perintah lebih pendek dengangit branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
chiborg
4
Hanya menunjukkan bahwa Anda harus menjadi master sebelum melakukan ini, karena git branch -dmembandingkan cabang melawan HEAD.
Steve Bennett
Luar biasa! Saya mencari dan mencari ini. Saya berharap saya telah melihat jawaban Anda sebelum akhirnya mencari tahu sendiri. Itu akan menyelamatkan saya beberapa menit. Inilah jawaban saya yang lain: stackoverflow.com/questions/15661853/…
Karl Wilbur
1
Saya berakhir dengan alias git yang sama, potongan bekas pakai karena awk tidak bekerja karena beberapa alasan:prunelocal = !sh -c \"git checkout -q master && git fetch -q --prune && git branch -vv | git grep ': gone]' | cut -d' ' -f3 | xargs git branch -d\"
Zitrax
3
Oh kawan ... sial kamu PERLU memperbarui jawabanmu untuk memberi tahu orang-orang bahwa mereka harusnya ahli. Lakukan saja ini dari cabang yang berbeda. @ stevebennet2 terima kasih atas komentar yang informatif
GrayedFox
53

Seseorang dapat mengkonfigurasi Git untuk secara otomatis menghapus referensi ke cabang jarak jauh yang dihapus saat mengambil:

git config --global fetch.prune true

Saat menelepon git fetchatau git pullsesudahnya, referensi ke cabang jauh yang dihapus bisa dihapus secara otomatis.

wedesoft
sumber
5
ini tidak menghapus cabang lokal, hanya referensi ke mereka, kan?
Clint Eastwood
@ClintEastwood Ini hanya menghapus referensi ke cabang jarak jauh . Anda dapat mendaftar referensi ke cabang jauh menggunakan git branch -r.
wedesoft
52

Ada paket NPM rapi yang melakukannya untuk Anda (dan itu harus bekerja lintas platform).

Instal dengan: npm install -g git-removed-branches

Dan kemudian git removed-branchesakan menunjukkan semua cabang lokal basi, dan git removed-branches --pruneuntuk benar-benar menghapusnya.

Info lebih lanjut di sini.

tzachs
sumber
1
Ini seharusnya memiliki lebih banyak upvotes. Terima kasih telah membuat hidup mudah, terlepas dari platform.
Enkripsi
Ekstensi kecil yang berguna. Diinstal dan bekerja dengan baik pada Windows 10. Catatan kecil: ia menganggap cabang yang tidak digabungkan sebagai prune-mampu (kesalahan saat menjalankan --prune, meskipun branch -d dipanggil) .. namun demikian, tidak dilambangkan seperti pada awal daftar ditampilkan.
user2864740
1
Ini jawaban favorit saya. npx git-removed-branchesbekerja seperti mimpi.
Drazisil
Iya! Ini seharusnya memiliki lebih banyak suara positif! solusi yang begitu sederhana dan intuitif untuk pemula cli
geoseong
Akan bermanfaat untuk memberikan ikhtisar tentang apa yang dilakukan alat ini dari perspektif git.
ryanwebjackson
41

Solusi Windows

Untuk Microsoft Windows Powershell:

git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}

Penjelasan

git checkout master beralih ke cabang master

git remote update origin --prune memangkas cabang-cabang terpencil

git branch -vvmendapat output verbose dari semua cabang ( referensi git )

Select-String -Pattern ": gone]" hanya mendapat catatan di mana mereka telah dihapus dari jarak jauh.

% { $_.toString().Split(" ")[0]} dapatkan nama cabang

% {git branch -d $_} menghapus cabang

chris31389
sumber
Contoh yang bagus. atau gunakan git remote prune origin-string juga sepertinya tidak cocok dengan versi terbaru git. Pertimbangkan untuk menggunakanConvertFrom-String -TemplateContent
Bernie White
3
Sepertinya git versi terbaru menambahkan beberapa spasi tambahan, sehingga Split tidak berfungsi untuk mendapatkan nama cabang. Lakukan .toString (). Trim (). Split ("") dan itu akan
Chris Hynes
Ini milik saya:git checkout master; git pull; git remote prune origin; git branch --merged | select-string -notmatch "master" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Omzig
@ Omzig Apa yang dilakukannya berbeda? Bisakah Anda memberikan penjelasan>
chris31389
@ chris31389, saya memiliki tarikan di sana untuk mendapatkan semua yang saya lewatkan dari master, dan saya mengubah cabang menjadi --ergerged dan tidak menguasai, saya ingin memastikan bahwa saya hanya menghapus cabang --ergerged. Itu hanya membuat saya merasa lebih baik;)
Omzig
27

Ini akan mencantumkan cabang lokal yang cabang pelacakan jarak jauh dihapus dari jarak jauh

$ git remote prune origin --dry-run

Jika Anda ingin menghilangkan referensi cabang lokal ini dari lokal yang tidak terlacak

$ git remote prune origin
027
sumber
19
Ini tidak menjawab pertanyaan, ini adalah apa yang sudah diketahui OP.
Ken Williams
2
Saya juga setuju, tetapi ketika Anda mencari "Cara memangkas cabang pelacakan lokal yang tidak ada pada jarak jauh lagi", ini adalah tautan teratas dan jawaban ini cocok dengan judul (bukan jika seseorang telah membaca deskripsi lengkap yang dimaksud), bahwa adalah alasan untuk suara terbanyak :)
027
Ini tidak menghapus cabang lokal. Masih di sana setelah menjalankan ini
Xin
@Xin mencoba menjalankan perintah tanpa argumen --dry-run karena ia tidak akan benar-benar mengeksekusi perintah, tetapi menunjukkan kepada Anda apa yang akan berubah.
Torsten Ojaperv
19

Sebagai catatan @tzacks ... ada paket npm yang berguna untuk ini. Kerjakan saja:

npx git-removed-branches --prune

(Saya akan berkomentar tetapi tidak cukup reputasi)

Johnshew
sumber
1
Menawan. Tidak ada masalah apa pun. Senang ini jawaban penuh!
Dan Rayson
1
Ini harus di atas. Bekerja di Windows juga.
tomtastico
14

Jika menggunakan Windows dan Powershell, Anda dapat menggunakan yang berikut untuk menghapus semua cabang lokal yang telah digabungkan ke cabang yang saat ini diperiksa:

git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_}

Penjelasan

  • Daftar cabang saat ini dan cabang yang telah digabungkan ke dalamnya
  • Menyaring cabang saat ini
  • Bersihkan semua spasi awal atau akhir dari gitoutput untuk setiap nama cabang yang tersisa
  • Menghapus cabang lokal yang digabungkan

Sebaiknya jalankan git branch --mergedsendiri dengan sendirinya hanya untuk memastikan itu hanya akan menghapus apa yang Anda harapkan.

(Porting / otomatis dari http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositor// )

Agas
sumber
10

Satu-liner yang lebih pendek dan lebih aman:

git branch -d $(git branch --merged | cut -c 3- | grep -v master)

Pastikan untuk checkout ke cabang yang belum digabung, sebelum menjalankannya. Karena Anda tidak dapat menghapus cabang yang saat ini Anda laporkan.

FelikZ
sumber
3
apakah ini juga akan menghapus 'tuan' Anda?
dcsan
2
Jika saat ini Anda masuk ke master maka tidak, jika tidak
FelikZ
1
Untuk melewati master, Anda bisa git branch -d $(git branch --merged | cut -c 3- | grep -v master)
mem
Ini tidak aman dan seseorang di masa depan tanpa sadar akan menghapus cabang utama mereka
jasoneminara
1
@jasoneminara #dcsan Saya telah memperbarui cuplikan, sehingga melompati cabang master. #mozillalives terima kasih
FelikZ
9

Saya menginginkan sesuatu yang akan membersihkan semua cabang lokal yang melacak cabang jarak jauh, pada origin, di mana cabang jarak jauh telah dihapus ( gone). Saya tidak ingin menghapus cabang lokal yang tidak pernah disetel untuk melacak cabang jarak jauh (yaitu: cabang dev lokal saya). Juga, saya ingin satu-liner sederhana yang hanya menggunakan git, atau alat CLI sederhana lainnya, daripada menulis skrip khusus. Saya akhirnya menggunakan sedikit grepdan awkuntuk membuat perintah sederhana ini, kemudian menambahkannya sebagai alias di blog saya ~/.gitconfig.

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D

Berikut adalah git config --global ...perintah untuk menambahkan ini dengan mudah git prune-branches:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

CATATAN: Penggunaan -Dbendera git branchbisa sangat berbahaya. Jadi, dalam perintah config di atas saya menggunakan -dopsi untuk git branchdaripada -D; Saya menggunakan -Dkonfigurasi aktual saya. Saya menggunakan -Dkarena saya tidak ingin mendengar Git mengeluh tentang ranting-ranting yang tidak terbakar, saya hanya ingin mereka pergi. Anda mungkin menginginkan fungsi ini juga. Jika demikian, cukup gunakan -Dalih-alih -ddi akhir perintah konfigurasi itu.

Karl Wilbur
sumber
8

Untuk menghapus cabang jarak jauh:

$git remote prune origin

Untuk menghapus cabang lokal yang sudah digabungkan:

$git branch -D $(git branch --merged)
Aniket
sumber
Bekerja untukku. Terima kasih.
AndroidRuntimeException
2
(cabang git --merged) juga mengembalikan 'master' untuk saya. Dan cabang-cabang lain yang belum dihapus pada remote.
Tom G
8
Ini menghapus cabang master saya.
Greg
@Reg Hanya secara lokal, kan?
GC_
5

Tampaknya tidak ada one-liner yang aman, terlalu banyak kasus tepi (seperti cabang yang memiliki "master" sebagai bagian dari namanya, dll). Paling aman adalah langkah-langkah ini:

  1. git branch -vv | grep 'gone]' > stale_branches.txt
  2. lihat file dan hapus baris untuk cabang yang ingin Anda pertahankan (seperti cabang master!); Anda tidak perlu mengedit konten baris apa pun
  3. awk '{print $1}' stale_branches.txt | xargs git branch -d
Oliver
sumber
5

Berdasarkan jawaban di atas, saya menggunakan liner yang lebih pendek ini:

git remote prune origin | awk 'BEGIN{FS="origin/"};/pruned/{print $2}' | xargs -r git branch -d

Juga, jika Anda sudah memangkas dan memiliki cabang menjuntai lokal, maka ini akan membersihkannya:

git branch -vv | awk '/^ .*gone/{print $1}' | xargs -r git branch -d
hidralisk
sumber
1
Tidak berfungsi jika ada nama cabang Anda /di dalamnya
theicfire
4

tidak yakin bagaimana melakukan semuanya sekaligus, tetapi git git branch -d <branchname>akan menghapus cabang lokal SAJA jika benar-benar digabungkan. Perhatikan huruf kecil d.

git branch -D <branchname> (perhatikan ibukota D) akan menghapus cabang lokal terlepas dari status gabungannya.

NHDaly
sumber
Di Windows, jawaban lain tidak berfungsi untuk saya. Menggunakan jawaban ini dengan saklar -D sederhana memang (meskipun cabang sudah "dihapus").
Bisakah kita melakukannya untuk semua cabang sekaligus?
Teoman shipahi
3

Anda dapat menggunakan perintah ini:

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

Git Clean: Hapus Cabang yang Sudah-Digabung termasuk penguraian perintah

sendon1982
sumber
Anda tidak perlu menyaring semua cabang (ex master). Jika "digabung" maka itu berarti itu akan menghapus salinan lokal Anda, tetapi "git checkout dev" akan membuat cabang lokal dari jarak jauh jika belum ada
csga5000
Tetapi daftar cabang lokal masih ada bahkan jika mereka digabungkan. Perintah ini adalah untuk menghapus cabang-cabang ini yang telah dihapus dari jarak jauh.
sendon1982
tanda bintang pada awalnya berarti cabang saat ini, ketika Anda menjalankan perintah pada cabang yang berbeda tidak akan berfungsi dengan baik
OzzyCzech
2

Berdasarkan jawaban di atas saya datang dengan solusi satu baris ini:

git remote prune origin; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d
gagarwal
sumber
2

Menggunakan varian pada jawaban @ wisbucky, saya menambahkan yang berikut sebagai alias ke ~/.gitconfigfile saya :

pruneitgood = "!f() { \
    git remote prune origin; \
    git branch -vv | perl -nae 'system(qw(git branch -d), $F[0]) if $F[3] eq q{gone]}'; \
}; f"

Dengan ini, simpel git pruneitgoodakan membersihkan cabang lokal & jarak jauh yang tidak lagi dibutuhkan setelah penggabungan.

Ken Williams
sumber
2

Versi Powershell dari git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

git branch --merged master | %{ if($_ -notmatch '\*.*master'){ git branch -d "$($_.Trim())" }}

Ini akan menghapus semua cabang lokal yang telah digabungkan menjadi master, saat Anda berada di cabang master .

git checkout master untuk menukar.

Kevin George
sumber
1

Varian Schleis tidak berfungsi untuk saya (Ubuntu 12.04), jadi izinkan saya mengusulkan varian (jelas dan mengkilap :) saya:

Varian 1 (Saya lebih suka opsi ini):

git for-each-ref --format='%(refname:short) %(upstream)' refs/heads/ | awk '$2 !~/^refs\/remotes/' | xargs git branch -D 

Varian 2:

Sebuah. Lari kering:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | awk '{print "git branch -D " $1}'

b. Hapus cabang:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | xargs git branch -D
daniilyar
sumber
1

Berikut ini adalah adaptasi dari jawaban @ wisbucky untuk pengguna Windows:

for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d

Saya menggunakan posh-git dan sayangnya PS tidak suka yang telanjang for, jadi saya membuat skrip perintah polos bernama PruneOrphanBranches.cmd:

@ECHO OFF
for /f "tokens=1" %%i in ('git branch -vv ^| findstr ": gone]"') DO CALL :ProcessBranch %%i %1

GOTO :EOF

:ProcessBranch
IF /I "%2%"=="-d" (
    git branch %1 %2
) ELSE (
    CALL :OutputMessage %1
)
GOTO :EOF

:OutputMessage
ECHO Will delete branch [%1] 
GOTO :EOF

:EOF

Sebut saja tanpa parameter untuk melihat daftar, lalu panggil dengan "-d" untuk melakukan penghapusan atau "-D" yang sebenarnya untuk cabang apa pun yang tidak sepenuhnya digabungkan tetapi yang ingin Anda hapus tetap.

Sam C
sumber
Ini tidak bekerja untuk saya, entah bagaimana, :atau : (dengan spasi) di findstrmenyebabkannya untuk mencocokkan segalanya setiap waktu - saya hampir menghapus master. Namun, menggunakan regex bekerja dengan baik:git branch -vv ^| findstr /R " \[origin/[0-9]+: gone\] "
Josh
1

Coba ini di git bash, untuk mengambil dan memangkas referensi ke cabang yang dihapus, dan kemudian memangkas cabang lokal yang melacak yang dihapus:

git fetch -p && git branch -d `git branch -vv | grep ': gone]' | awk '{print $1}' | xargs`

Ingatlah untuk checkout terlebih dahulu cabang yang tidak akan dihapus, sehingga tidak memblokir penghapusan cabang.

Guillermo Gutiérrez
sumber
0

Saya telah mengubah jawaban yang diterima menjadi skrip yang kuat. Anda akan menemukannya di repositori git-extensions saya .

$ git-prune --help
Remove old local branches that do not exist in <remote> any more.
With --test, only print which local branches would be deleted.
Usage: git-prune [-t|--test|-f|--force] <remote>
Ingo Karkat
sumber
0

Saya mencapai halaman ini mencari jawaban untuk "bagaimana cara saya menghapus cabang yang diperiksa secara lokal yang tidak lagi memiliki cabang di hulu"

Saya juga tidak peduli apakah cabang lokal telah digabung atau belum, karena pemipaan ke git branch -dhanya akan memperingatkan, bukannya menghapus cabang lokal yang tidak dimusnahkan.

git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3 | egrep -v -f /dev/fd/0 <(git branch -a | grep -v origin) | grep branch_prefix_that_I_care_about | xargs git branch -d

# translation
# git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3
## this finds all remote branch names minus the "remote/origin/" part
#
# <(git branch -a | grep -v origin)
## this finds all local branch names and redirects it into the previous command
#
# egrep -v -f /dev/fd/0 STUFF
## this is doing some weird magic that I'm grokking as "take the set difference from whatever was piped in"
#
#
# overall translation: (STUFF TO CONSIDER) | egrep magic <(STUFF TO REMOVE FROM CONSIDERATION) | do cool things with resulting stuff
Meredith
sumber
0

Dalam Powershell :

git branch -D (git branch --merged |% { $_.trim() } )
Raúl Salinas-Monteagudo
sumber
0

Inilah solusi saya:

git fetch -p
git branch -vv | grep ": gone" | awk '{print $1}' | xargs git branch -d
  • -p adalah untuk menghapus referensi pelacakan jarak jauh yang tidak lagi ada di remote. Jadi langkah pertama akan menghapus referensi ke cabang jarak jauh.

  • -vv adalah untuk menunjukkan sha1 dan melakukan baris subjek untuk setiap kepala, bersama dengan hubungan dengan cabang hulu (jika ada). Langkah ke-2 akan mendapatkan semua cabang lokal dan perintah grep akan menyaring cabang yang telah dihapus.

Neeraj Bansal
sumber
Bahkan lebih kecil (seperti yang dijelaskan dalam komentar lain)git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
mrroboaat
-2

Hapus cabang apa pun yang tidak mutakhir dengan master

git co master && git branch | sed s/\*/\ / | xargs git branch -d 2> /dev/null
Jason Waldrip
sumber
-3

Saya cukup yakin itu git remote prune originyang Anda inginkan.

Anda dapat menjalankannya git remote prune origin --dry-rununtuk melihat apa yang akan dilakukannya tanpa membuat perubahan apa pun.

Jason Antman
sumber
12
Ini sebenarnya tidak menghapus cabang lokal itu sendiri.
Taytay
-16

Menggunakan GUI? Prosedur manual, tetapi cepat dan mudah.

$ git gui

Pilih "Cabang -> Hapus". Anda dapat memilih beberapa cabang dengan klik ctrl (windows) dan menghapus semuanya.

Pedro Ballesteros
sumber
Lucu juga betapa negatifnya jawaban ini. IMO pendekatan yang benar-benar valid jika Anda suka GUI.
serraosays