Hapus beberapa cabang jarak jauh di git

129

Saya memiliki anggota tim yang secara tidak sengaja mendorong lebih dari 150 cabang lokalnya ke repo pusat kami. Untungnya, mereka semua memiliki awalan yang sama. Menggunakan awalan itu, apakah ada perintah git atau skrip shell kecil yang keren yang dapat saya gunakan yang akan menghapus semuanya sekaligus?

Jake A. Smith
sumber

Jawaban:

151

Gunakan perintah berikut untuk menghapus semua cabang dengan PREFIXawalan di server jauh.

git branch -r | awk -F/ '/\/PREFIX/{print $2}' | xargs -I {} git push origin :{}

Anda mungkin ingin melakukan uji coba terlebih dahulu untuk melihat apakah cabang yang ingin Anda hapus:

git branch -r | awk -F/ '/\/PREFIX/{print $2}'
neevek
sumber
2
Saya suka ini karena ini satu liner dan saya bisa melakukan dry run dulu. Sayangnya, ada kesalahan dengan pesan ini: $ git branch -r | awk -F/ '/\/APR/{print $2}' | xargs -I {} git push origin :{} error: unable to push to unqualified destination: APR-04-DPH The destination refspec neither matches an existing ref on the remote nor begins with refs/, and we are unable to guess a prefix based on the source ref. error: failed to push some refs to 'GIT_URL'
Jake A. Smith
Dengan git branch -r | awk -F/ '/\/APR/{print $2}', dapatkah Anda melihat semua nama cabang berawalan APR terdaftar?
neevek
1
Oke, karena APR-04-DPHcabangnya sudah dihapus. Lihatlah pertanyaan-pertanyaan yang telah dijawab ini : ini dan ini dan juga ini . Jawaban atas pertanyaan tersebut mengatasi masalah yang sama, Anda mungkin ingin menguji sendiri solusinya.
neevek
26
jika Anda memiliki / di nama cabang Anda (jika Anda menggunakan git-flow atau semacamnya), cetaklah {$ 2 "/" $ 3} sebagai gantinya
ajma
4
Saya menggunakan msysgit di Windows, dan perintah berikut berfungsi untuk saya (sehubungan dengan komentar @ ajma untuk nama cabang yang mengandung garis miring:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %
rikoe
96

Jika Anda menyukai pendekatan yang lebih sederhana, misalnya hapus 3 atau 4 cabang:

git push origin --delete <branch1> <branch2> <branch3>

Penting: Hanya berfungsi di Git v1.7.0 dan yang lebih baru.

jfeston.dll
sumber
6
Saya akhirnya menggunakangit branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete
Aram Kocharyan
36

Terima kasih kepada Neevek untuk solusi yang hebat dan elegan!

Tetapi saya mengalami masalah dengan garis miring pada nama cabang (saya menggunakan Git Flow), karena awkpemisah bidang /( -Fopsi)

Jadi solusi saya didasarkan pada Neevek , tetapi dengan benar mem-parsing nama cabang /. Dalam hal ini saya menganggap remote Anda dipanggil origin. Perintah untuk menghapus cabang jarak jauh dengan nama yang dilihat dengan PATTERN:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -I {} git push origin :{}

Dan jangan lupa untuk memeriksa apa yang akan Anda hapus:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}'

TIPS BERGUNA: Jika nama cabang Anda (tanpa origin/awalan) disimpan dalam file teks (satu nama cabang per baris), jalankan saja:

cat your_file.txt | xargs -I {} git push origin :{}
Dmitriy
sumber
2
Gunakan xargs -a file -Lsebagai ganti cat file | xargs. Bahkan lebih sederhana xargs -a file git push --delete origin.
musiKk
15

Ini mungkin jawaban duplikat tetapi di bawah diuji dan bekerja untuk saya dengan sempurna.

  1. Hapus cabang lokal dengan paksa

git branch -D nama-cabang

  1. Hapus cabang jarak jauh

git push origin - hapus nama-cabang

  1. Hapus lebih dari 1 cabang lokal

git branch -D nama-cabang1 nama-cabang2

  1. Hapus lebih dari 1 cabang jarak jauh

git push origin - hapus nama-cabang1 nama-cabang2

  1. Hapus cabang lokal dengan awalan. Misalnya, fitur / *

git branch -D $ (git branch --list 'feature / *')

git branch -D backticks $ (git branch --list 'feature / *' backticks )

  1. Buat daftar cabang jarak jauh dengan awalan.

git branch -r | grep -Eo 'fitur /.*'

  1. Hapus cabang jarak jauh dengan awalan

git branch -r | grep -Eo 'fitur /.*' | xargs -I {} git push origin: {}

Naren
sumber
2
saya pikir Anda bermaksud untuk melepaskan diri dari serangan balik di langkah 5
GPL
Bagaimana cara menambahkan backticks?
Naren
1
@Naren: masalahnya adalah bahwa pemformatan penurunan harga mengubah backticks Anda menjadi perintah gaya. Saya menggantinya dengan metode substitusi perintah yang berbeda (misalnya "$ (command)" setara dengan `perintah` tetapi tidak diterjemahkan dengan penurunan harga menjadi sesuatu yang aneh.) Hal lain yang dapat Anda lakukan adalah menghindari backticks dengan '\'
Stabledog
13

Sama dengan grep: git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}.

branch -racara origin/prefix/branchname. Jadi itu akan memakan waktu prefix/branchname.

Kirby
sumber
Saya pikir yang Anda maksud xargs -I {} git push origin :{}, bukan -i.
jojo
1
@jojo, AFAIK, untuk -iitu menggunakan pengganti default {}tetapi dengan -IAnda dapat mendeklarasikannya sendiri. ... baru saja ditemukan di manual:-i ... the same as -I{}
Kirby
10

Solusi Neevek elegan, tetapi bisa lebih baik: solusi seperti yang diusulkan panggilan 'git push' sekali per cabang, yang berarti jaringan tambahan perjalanan pulang pergi per cabang akan dihapus. Karena Anda tetap menggunakan awk, mengapa tidak menggunakannya untuk mengawali ':' dan kemudian xargs dapat memanggil 'git push' tepat sekali dan menghapus semua cabang sekaligus:

Jalankan uji coba untuk membuat daftar cabang yang akan dihapus:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}'

Solusi terakhir untuk benar-benar mendorong penghapusan:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin
kekurangan
sumber
2
Ia bekerja dengan sempurna dalam situasi di mana Anda tidak dapat menggunakan opsi "-I" untuk xargs ketika Anda memiliki versi bash yang lebih rendah atau menggunakan git bash versi windows.
zchholmes
Saya memiliki solusi xargs: replstr may not be emptydengan Neevek, mungkin versi git .. git version 1.9.5Tapi ini bekerja dengan baik untuk saya. Terima kasih untuk Anda berdua
IamFace
8

sumber daya https://coderwall.com/p/eis0ba

    1 - List all your remote branches:

    $ git branch -r

    2 - Filter the branches by some regular expression. In this case I'm interested in deleting any branch with the 'feature-' prefix:

    $ git branch -r | awk -F/ '/\/feature-/{print $2}'
    3 - Pipe the last command to git push to delete them:
    # **Edit** - Removed extra colon, which is not needed
    $ git branch -r | awk -F/ '/\/feature-/{print $2}' | xargs -I {} git push origin {}
    4 - Grab a beer.

    5 - Remove any local reference to those branches:

    $ git remote prune origin
Ashish Sajwan
sumber
Terima kasih ini berhasil untuk saya. Dalam kasus mu, saya dapat menghapus beberapa cabang lokal. Terima kasih!
Prashant Kabade
5

Terima kasih kepada Steve dan Neevek, saya menemukan solusi yang bekerja cukup baik untuk saya yang menurut saya layak untuk dibagikan:

Solusi Steve berhasil untuk saya dengan satu penyesuaian kecil. Remote saya diberi nama origin/feature/some-feature-namejadi saya memangkas awk:

git branch -r | awk -Forigin/ '/\/feature/ {print $2 $3}' | xargs -I {} git push origin :{}

Sekarang melakukan aliran penghapusan kecil yang bagus:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
To github.com:project/project-name.git
- [deleted]         feature/search-placeholder
To github.com:project/project-name.git
- [deleted]         feature/server-error-message
To github.com:project/project-name.git
- [deleted]         feature/six-point-asterisk

Saya bertanya-tanya apakah ada yang punya ide untuk solusi yang lebih elegan, yang mungkin menghasilkan sesuatu seperti ini (skrip CLI saya sangat buruk, jadi saya butuh waktu untuk memikirkannya):

git push origin :feature/search-min-chars :feature/search-placeholder :feature/server-error-message :feature/six-point-asterisk

Ini akan menghasilkan satu keluaran yang bagus dengan satu permintaan jaringan:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
- [deleted]         feature/search-placeholder
- [deleted]         feature/server-error-message
- [deleted]         feature/six-point-asterisk
andrewmart.in
sumber
4

Terima kasih untuk Neevek. Ini bekerja dengan baik setelah mengkonfigurasi ulang untuk tujuan saya:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}

Saya juga perlu mempertimbangkan struktur folder. Cabang fitur saya berada dalam struktur folder seperti origin / feature / PREFIX-FEATURENUMBER. Jadi saya harus membangun pola saya dari $ 2 = folder + $ 3 = branchname.

pengguna3416278
sumber
4

Semua orang menggunakan awk, tidak yakin mengapa. Saya merasa itu lebih kompleks. Inilah yang saya gunakan untuk menghapus semua cabang jarak jauh di forkremote saya :

$ git branch -r --list 'fork/*' | sed 's/fork\///' | xargs git push --delete fork

Lempar di grepantara xargsdan sedjika Anda perlu memfilter daftar ke hanya subset cabang jauh.

void.pointer
sumber
1
Terima kasih banyak. Yang ini benar-benar berfungsi untuk saya di antara semua solusi .. grep mengembalikan cabang lengkap dengan nama jarak jauh juga origin/blaprefix_anotherbla. Tapi menggunakan sedmenanganinya dengan baik. Keuntungan lain dari pendekatan ini, adalah saya menggunakan bitbucket dan saya tidak perlu memasukkan kata sandi otentikasi untuk setiap penghapusan cabang secara manual. Yang ini menghapus semua cabang dalam satu batch.
Madhur Bhaiya
Untuk menghapus semua cabang git branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}
greenkeeper
4

Saya menyadari ini untuk perintah git, tetapi jika Anda mencari solusi alternatif untuk melakukan hasil yang serupa atau sama:

Anda dapat melakukannya dari sini (Git Remove Remote Branches):

Kemudian pilih cabang yang Anda inginkan:

Pastikan Anda memiliki izin untuk menghapus cabang jarak jauh.

Ewin Hong
sumber
Ini harus menjadi jawaban teratas, ini adalah platform independen.
karmington
Apa software itu dan apakah tersedia untuk linux?
abhisekp
1

Github juga memiliki UI dan mekanisme yang bagus untuk menghapus cabang dengan cepat, itu jika Anda lebih suka menggunakan UI

Alex
sumber
1
Ya, itu didokumentasikan di sini , tetapi Anda masih harus mengklik sekali untuk setiap cabang. Solusi pilihan teratas di sini adalah cara terbaik untuk melakukan banyak cabang yang dapat Anda tulis dengan regex untuk dicocokkan.
thewoolleyman
0

Saya mencoba menghapus semua cabang jarak jauh asal / rilis / r1-1 *, karenanya baris perintah berikut berfungsi dengan baik.

git branch -r | awk -Forigin/ '/\/*r1-1/ {print $2}' |  xargs -I {} git push origin :{}
Atish Narlawar
sumber
0

Saya tidak dapat menggunakan awk karena kami menggunakan struktur garis miring untuk nama cabang kami.

git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i  sh -c 'git push origin --delete {}'

Ini mendapatkan semua cabang jarak jauh, dapatkan hanya satu untuk satu pengguna, jarak jauh string "origin /" dan jalankan penghapusan pada masing-masing.

Patrick Desjardins
sumber
0

Uji coba kering:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} echo {}

Hapus cabang jarak jauh:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Hapus hanya cabang jarak jauh yang digabungkan sepenuhnya:

git branch -r --merged --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Penjelasan:

sed "s/origin\///"akan dihapus origin/dari nama cabang. Tanpa melepaskannya saya mendapat:remote ref does not exist

Tobias Ernst
sumber
0

Jawaban sebelumnya membantu saya untuk menghapus semua cabang rilis dari 2018. Saya menjalankan ini di command prompt windows 10 saya. Saya telah menginstal clink , jadi Linux seperti perintah bekerja untuk saya.

Jalankan Kering:

git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}

Jika dry run menunjukkan cabang yang tidak di remote / origin. Jalankan di bawah perintah git prune untuk memperbaiki dan memeriksa lagi.

git remote prune origin

Hapus setelah Anda puas dengan hasil di atas:

git branch -a | grep -o "release-.*2018" | xargs -I {} git push origin --delete {}

Jika Anda melihat: error: unable to delete 'release-...2018': remote ref does not exist. Kemudian jalankan perintah prune sebelumnya dan coba lagi.

Damodar Bashyal
sumber
-4

Peringatan: Ini akan menghapus semua cabang jarak jauh. Gunakan dengan hati-hati.

Saya pikir cara saya menghapus cabang jarak jauh adalah yang terbaik.

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

Peringatan: Ini akan menghapus semua cabang jarak jauh. Gunakan dengan hati-hati.

Dmytro Gorpynenko
sumber
4
Tidak dipilih sebagai troll yang jelas. Akan menghapus jika saya punya hak.
Jake A. Smith
di mana kamu menemukan trolling?
Dmytro Gorpynenko
2
ini tidak benar, Anda kehilangan beberapa argumen penting untuk xargs, dan itu tidak menjawab pertanyaannya.
Rob
@ JakeA.Smith Jake, saya kira Anda berpikir bahwa kode ini akan menghapus master jarak jauh - yang tidak terjadi karena grep -v master menemukan segalanya kecuali master.
Vadim Samokhin
@Rob apa yang salah di sini? Pernyataan akhir yang dieksekusi akan menjadi seperti git push: some_branch: another_branch, yang benar-benar benar.
Vadim Samokhin