Hapus cabang Git lokal setelah menghapusnya pada repo jarak jauh


162

Saya ingin memiliki repositori lokal dan jarak jauh saya selalu sinkron dalam hal cabang.

Setelah ulasan Tarik Permintaan pada GitHub, saya menggabungkan dan menghapus cabang saya di sana (jarak jauh). Bagaimana saya bisa mengambil informasi ini di repositori lokal saya dan meminta Git untuk menghapus versi lokal cabang saya juga?


Apakah Anda ingin menghapus cabang pelacakan jarak jauh, cabang lokal, atau keduanya? Anda sebenarnya dapat menulis alias (bash atau git) yang akan mengambil semua cabang jarak jauh yang dihapus, dan menemukan salinan lokal untuk dihapus juga, semuanya dalam satu perintah.

Mungkin coba gunakan perintah berikut untuk membuat sesuatu, git ls-remotedan git show-ref.

Juga, Anda mungkin ingin memeriksa git symbolic-refdan git update-ref.

terima kasih atas bantuan Anda, saya akhirnya menemukan jawabannya di tempat lain. Lihat tanggapan saya.
sf89

Jawaban:


180

Cara cepat

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

NB: jika Anda tidak aktif master, ini berpotensi menghapus cabang. Teruslah membaca untuk "cara yang lebih baik".

Pastikan kita tetap menguasai

Anda dapat memastikan bahwa master, atau cabang lainnya dalam hal ini, tidak dihapus dengan greplebih. Dalam hal ini Anda akan pergi:

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

Jadi jika kita ingin tetap master, developdan stagingmisalnya, kita akan pergi:

git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d

Jadikan ini sebagai alias

Karena agak panjang, Anda mungkin ingin menambahkan alias ke .zshrcatau .bashrc. Tambang disebut gbpurge(untuk git branches purge):

alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'

Kemudian muat ulang .bashrcatau .zshrc:

. ~/.bashrc

atau

. ~/.zshrc

Anda dapat menempatkan perintah di alias dan menjadikannya perintah tunggal. Namun, karena branchini adalah porselen dan bukan perintah plumbing , waspadalah terhadap perubahan UI di versi Git yang akan merusaknya.

1
Sempurna! Perhatikan bahwa mengikuti Alur Kerja Github cabang lokal masterakan dihapus.
Rubens Mariuzzo

Tidak cukup yakin itu tetap di sana (saya menggunakannya setiap hari dan sepertinya tidak melakukan itu).
sf89

4
FYI jika Anda ingin menyimpan banyak cabang, Anda dapat menggunakan grep tunggal, seperti: grep -Ev '(\*|master|important-branch)'
Andrew Burns

4
Jika Anda ingin meletakkan ini ~/.gitconfigsebagai gantinya, tambahkan berikut ini ke [alias]bagian: gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"(tidak perlu menggunakan () dalam ekspresi grep).
dskrvk

82

Saya menggunakan aliran yang sama dengan GitHub, dan tidak menemukan jawaban sebelumnya memuaskan saya, karena git branch --mergeddaftar cabang yang digabung, tetapi tidak semua dari mereka dihapus dari jarak jauh dalam kasus saya. Jadi, ini berhasil bagi saya:

git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d

dimana:

  • git fetch --all -p: perbarui status cabang lokal
  • git branch -vv: daftar status cabang lokal
  • grep ": gone]": filter yang dihapus
  • awk '{ print $1 }': ekstrak nama mereka
  • xargs -n 1 git branch -d: meneruskan nama ke perintah hapus

Catatan: jika Anda mau, Anda bisa menggunakan -D bukannya -d, yang memberlakukan penghapusan.

Sebagai contoh:

someUsr@someHost:~/repo$ git branch -a
basic-testing
integration-for-tests
* master
origin
playground-for-tests
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

someUsr@someHost:~/repo$ git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
Fetching origin
Deleted branch integration-for-tests (was fbc609a).
Deleted branch playground-for-tests (was 584b900).

someUsr@someHost:~/repo$ git branch -a
basic-testing
* master
origin
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

Referensi:

http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches


3
Saya mengambil kebebasan untuk memastikan bahwa saya akan selalu melakukan itu terhadap tuan, oleh karena itu: git checkout master; git pull origin master; git fetch --all -p; git branch -vv | grep gone | awk '{ print $1 }' | xargs -n 1 git branch -d Skrip dan penjelasan yang hebat, terima kasih untuk itu :)
Miguelgraz

Catatan yang branch -vvmenunjukkan pesan komit terakhir dari cabang. Jika Anda telah "pergi" dalam pesan itu, maka grep goneakan mengenai cabang itu juga. Jadi, grep ": gone]"mungkin sedikit lebih aman untuk digunakan.
chawkinsuf

1
Ini adalah jawaban aktual untuk pertanyaan itu. Terima kasih.
Andrei Gladkyi

1
Bahkan lebih baik:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Jakub Bochenski

3
Selain membutuhkan, ini -Dbukan -djawaban yang tepat!
Cas

72

mencoba:

git pull --prune

yang menghapus cabang lokal Anda, jika cabang jarak jauh yang terkait dihapus.

Diperbarui:

Pernyataan di atas tidak benar.

Bahkan, menjalankan hanyagit pull --prune akan MEMINDAHKAN cabang pelacakan jarak jauh seperti

remote / asal / fff
remote / asal / dev
remote / asal / master

Kemudian, Anda dapat menjalankan git branch -runtuk memeriksa cabang pelacakan jarak jauh yang tersisa di mesin Anda. Misalkan cabang kiri adalah:

asal / dev
asal / master

yang berarti cabang origin/fffdihapus.

Jadi, setelah berlari git pull --prune, jalankan saja:

git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)

Anda dapat mengetahui semua cabang lokal yang:

  1. tidak memiliki cabang terpencil correspoding lagi;
  2. dapat dihapus dengan aman.

lalu, <the command above> | xargs git branch -dbisa menghapus semuanya.


42
Jawaban ini tidak sepenuhnya benar. The --prunebendera hanya akan menghapus remote pelacakan cabang, tidak cabang lokal.

3
Setuju dengan @Cupcake di sini, ini tidak mencapai apa yang saya cari di sini.
sf89

6
Tidak akan melakukan upvote, tetapi inilah yang saya butuhkan setelah menghapus cabang lokal dan kemudian menghapus dari GitHub tetapi mereka masih ada sebagai remote di perintah git remote -v saya.
Spechal

8
Anda juga dapat melakukannya git fetch --prune, itulah pilihan saya
e_m0ney

1
Namun kesalahan Git lain dari saran yang ditemukan di Stack overflow ... git pull --prunemenghasilkan "Anda diminta menarik dari '--prune' jarak jauh, tetapi tidak menentukan cabang. Karena ini bukan remote yang dikonfigurasi secara default untuk cabang Anda saat ini, Anda harus menentukan cabang pada baris perintah. "
jww

23

Ini harus bekerja untuk menghindari penghapusan cabang master dan pengembangan dengan solusi yang diterima:

git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d

16

Untuk orang yang menggunakan PowerShell, ini setara dengan jawaban di atas :

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. Saring semua cabang yang ditandai sebagai hilang
  2. Panggil git branch -Dmasing-masing cabang yang ditemukan

6

Tak satu pun dari ini bekerja untuk saya. Anda dapat melihat jawaban saya yang lain di sini: https://stackoverflow.com/a/34969726/550454

Tetapi pada dasarnya, saya sekarang memiliki ini di ~/.gitconfig:

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

5

Solusi yang sangat sederhana: hapus repo lokal Anda dan kloning remote lagi. Mungkin tidak tampak sangat elegan, tetapi sederhana dan Anda akan mengerti apa yang Anda lakukan tanpa membaca halaman manual :-).


1
Mengapa begitu banyak downvotes? Maksud saya jelas tidak efisien, terutama dengan repo yang lebih besar, tetapi ia melakukan apa yang diminta OP. Apakah ada alasan lain untuk tidak melakukan ini?
3ocene

6
Karena Anda akan kehilangan semua cabang lokal Anda, simpanan, komit tidak tercemar ... itu seperti memancing dengan dinamit.
sevenseacat

1
Hal yang sama terjadi ketika laptop yang Anda kerjakan entah bagaimana rusak, hilang, atau dicuri, jadi saya cenderung tidak menyimpan apa pun yang penting secara lokal. Sepertinya lebih baik bagi saya untuk hanya membuat cabang dan mendorongnya, bahkan untuk fitur kecil, dan menghapusnya setelah tidak berguna lagi.

1

Saya telah menulis satu baris ini untuk mendaftar semua cabang lokal yang tidak memiliki cabang jarak jauh yang sesuai:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -

Setelah ini selesai, menghapus cabang-cabang lokal ini mudah dengan xargs:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -|xargs -r git branch -d

ini juga mencantumkan saya master, tidak berfungsi seperti yang diharapkan; hati
Enrico

1

Saya hanya melakukan itu untuk menghapus cabang lokal gabungan:

git branch -d $(git branch --merged)

dan jika Anda ingin menghapus juga pelacakan yang tidak ada:

git pull --prune

1

Jika Anda baru saja mendorong dan menggabungkan cabang Anda untuk dikuasai, maka lakukan hal berikut di git bash:

git branch -d branch_name_to_delete

Jika Anda saat ini di cabang itu akan mendorong Anda kembali ke master. Pada titik ini lakukan tarik dengan

git pull

-2

Jawaban yang dipilih memang berpotensi menghapus master. Perhatikan contoh praktis di bawah ini.

Saya memiliki dua cabang fitur hemen_README dan hemen_BASEBOX yang digabung menjadi berkembang, dan kemudian berkembang digabung menjadi master. Cabang fitur hemen_README dan hemen_BASEBOX dihapus dari jarak jauh tetapi masih muncul secara lokal. Juga saya tidak menguasai secara lokal, tetapi pada pengembangan.

Dalam hal itu

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                      671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX                a535c0f added global exec paths to puppet manifest
        hemen_README                 ba87489 Updated Readme with considerable details
        master                       8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop       671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/hemen_BASEBOX a535c0f added global exec paths to puppet manifest
        remotes/origin/hemen_README  ba87489 Updated Readme with considerable details
        remotes/origin/master        2f093ce Merged in develop (pull request #3)

Jadi jika saya menjalankan perintah parsial di atas

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch --merged | grep -v "\*"
        hemen_BASEBOX
        hemen_README
        master

Perhatikan bahwa itu menunjukkan master juga, yang pada akhirnya akan dihapus.

Bagaimanapun saya bisa melakukannya. Saya membagikan log sesi saya dengan Anda tentang bagaimana saya mencapai itu.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin --dry-run
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [would prune] origin/hemen_BASEBOX
     * [would prune] origin/hemen_README
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin 
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [pruned] origin/hemen_BASEBOX
     * [pruned] origin/hemen_README

Saya baru saja memeriksa apa yang akan dipangkas dan kemudian memangkasnya. melihat perintah cabang di bawah ini kami telah mengurus remote

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX          a535c0f added global exec paths to puppet manifest
        hemen_README           ba87489 Updated Readme with considerable details
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

Sekarang lanjutkan dan hapus cabang lokal

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_BASEBOX 
    Deleted branch hemen_BASEBOX (was a535c0f).
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_README
    Deleted branch hemen_README (was ba87489).

Bagus sekarang cabang yang diinginkan.

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

Tentu saja ia berpotensi menghapus master. Silakan baca pertanyaan dengan seksama. Seperti yang saya katakan di sana, saya perlu cara untuk membersihkan barang-barang di rumah saya. Itu berarti menghapus semua cabang yang tidak lagi ada di remote. Jika master tidak ada lagi di sana, maka master itu juga akan hilang di mesin lokal Anda.
sf89
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.