Bagaimana saya bisa melakukan iterasi melalui semua cabang lokal di repositori saya menggunakan skrip bash. Saya perlu mengulang dan memeriksa apakah ada perbedaan antara cabang dan beberapa cabang jarak jauh. Ex
for branch in $(git branch);
do
git log --oneline $branch ^remotes/origin/master;
done
Saya perlu melakukan sesuatu seperti yang diberikan di atas, tetapi masalah yang saya hadapi adalah $ (git branch) memberi saya folder di dalam folder repositori bersama dengan cabang yang ada di repositori.
Apakah ini cara yang benar untuk mengatasi masalah ini? Atau apakah ada cara lain untuk melakukannya?
Terima kasih
for b in "$(git branch)"; do git branch -D $b; done
Jawaban:
Anda sebaiknya tidak menggunakan git branch saat menulis skrip. Git menyediakan antarmuka "pipa ledeng" yang secara eksplisit dirancang untuk digunakan dalam skrip (banyak implementasi saat ini dan historis dari perintah Git normal (tambahkan, checkout, gabung, dll.) Menggunakan antarmuka yang sama ini).
Perintah pemipaan yang Anda inginkan adalah git for-each-ref :
Catatan: Anda tidak memerlukan
remotes/
prefiks pada referensi jarak jauh kecuali Anda memiliki referensi lain yang menyebabkanorigin/master
kecocokan beberapa tempat di jalur pencarian nama ref (lihat “Nama referensi simbolik.…” Di bagian Revisi Menentukan dari git-rev-parse (1) ). Jika Anda mencoba untuk secara eksplisit menghindari ambiguitas, kemudian pergi dengan nama ref penuh:refs/remotes/origin/master
.Anda akan mendapatkan hasil seperti ini:
Anda dapat menyalurkan output ini ke sh .
Jika Anda tidak menyukai ide untuk membuat kode shell, Anda dapat melepaskan sedikit ketahanan * dan melakukan ini:
* Nama referensi harus aman dari pemisahan kata shell (lihat git-check-ref-format (1) ). Secara pribadi saya akan tetap menggunakan versi sebelumnya (kode shell yang dihasilkan); Saya lebih yakin bahwa tidak ada yang tidak pantas dapat terjadi dengannya.
Karena Anda menentukan bash dan mendukung array, Anda dapat menjaga keamanan dan tetap menghindari menghasilkan nyali dari loop Anda:
Anda bisa melakukan hal serupa
$@
jika Anda tidak menggunakan shell yang mendukung array (set --
untuk menginisialisasi danset -- "$@" %(refname)
menambahkan elemen).sumber
--merged
, apakah saya harus menduplikasi logika di cabang git? Pasti ada cara yang lebih baik untuk melakukan ini.git for-each-ref refs/heads | cut -d/ -f3-
git for-each-ref refs/heads --format='%(refname)'
for-each-ref
sekarang mendukung semua penyeleksi cabang seperti--merged
dangit branch
dangit tag
sekarang benar-benar diimplementasikan dengangit for-each-ref
sendirinya, setidaknya untuk kasus yang ada dalam daftar. (Membuat cabang dan tag baru bukan, dan seharusnya tidak menjadi, bagian darifor-each-ref
.)Ini karena
git branch
menandai cabang saat ini dengan tanda bintang, misalnya:jadi
$(git branch)
meluas ke misalnya* master mybranch
, dan kemudian*
meluas ke daftar file di direktori saat ini.Saya tidak melihat opsi yang jelas untuk tidak mencetak tanda bintang sejak awal; tapi Anda bisa memotongnya:
sumber
$(git branch | sed -e s/\\*//g)
.3-
solusi Anda .$(git branch | sed 's/^..//')
$(git branch | tr -d " *")
Bash builtin,,
mapfile
dibuat untuk inisemua cabang git:
git branch --all --format='%(refname:short)'
semua cabang git lokal:
git branch --format='%(refname:short)'
semua cabang git jarak jauh:
git branch --remotes --format='%(refname:short)'
iterasi melalui semua cabang git:
mapfile -t -C my_callback -c 1 < <( get_branches )
contoh:
untuk situasi spesifik OP:
sumber: Cantumkan semua cabang git lokal tanpa tanda bintang
sumber
Saya mengulang seperti itu misalnya:
sumber
Saya akan menyarankan
$(git branch|grep -o "[0-9A-Za-z]\+")
jika cabang lokal Anda diberi nama hanya dengan angka, az, dan / atau huruf AZsumber
Jawaban yang diterima benar dan seharusnya menjadi pendekatan yang digunakan, tetapi menyelesaikan masalah di bash adalah latihan yang bagus untuk memahami cara kerja cangkang. Trik untuk melakukan ini menggunakan bash tanpa melakukan manipulasi teks tambahan, adalah memastikan keluaran dari git branch tidak pernah diperluas sebagai bagian dari perintah yang akan dijalankan oleh shell. Hal ini mencegah asterisk berkembang dalam perluasan nama file (langkah 8) dari ekspansi shell (lihat http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html )
Gunakan bash saat membuat dengan perintah baca untuk memotong keluaran git branch menjadi beberapa baris. '*' Akan dibaca sebagai karakter literal. Gunakan pernyataan kasus untuk mencocokkannya, berikan perhatian khusus pada pola pencocokan.
Tanda bintang dalam konstruksi bash case dan dalam substitusi parameter harus di-escape dengan garis miring terbalik untuk mencegah shell menafsirkannya sebagai karakter yang cocok dengan pola. Spasi juga dikosongkan (untuk mencegah tokenisasi) karena Anda benar-benar mencocokkan '*'.
sumber
Pilihan termudah untuk diingat menurut saya:
git branch | grep "[^* ]+" -Eo
Keluaran:
Opsi -o dari Grep (--only-matching) membatasi keluaran hanya ke bagian masukan yang cocok.
Karena tidak ada spasi maupun * yang valid dalam nama cabang Git, ini mengembalikan daftar cabang tanpa karakter tambahan.
Edit: Jika Anda dalam keadaan 'kepala terpisah' , Anda harus memfilter entri saat ini:
git branch --list | grep -v "HEAD detached" | grep "[^* ]+" -oE
sumber
Apa yang akhirnya saya lakukan, diterapkan pada pertanyaan Anda (& terinspirasi oleh penyebutan ccpizza
tr
):git branch | tr -d ' *' | while IFS='' read -r line; do git log --oneline "$line" ^remotes/origin/master; done
(Saya sering menggunakan while loop. Sementara untuk hal-hal tertentu Anda pasti ingin menggunakan nama variabel runcing ["cabang", misalnya], sebagian besar waktu saya hanya mementingkan melakukan sesuatu dengan setiap baris masukan. Menggunakan 'garis' di sini bukan 'cabang' adalah anggukan untuk digunakan kembali / memori otot / efisiensi.)
sumber
Memperluas dari jawaban @ finn (terima kasih!), Berikut ini akan memungkinkan Anda beralih ke cabang tanpa membuat skrip shell yang mengganggu. Ini cukup kuat, selama tidak ada baris baru di nama cabang :)
Loop sementara berjalan dalam subkulit, yang biasanya baik-baik saja kecuali Anda menyetel variabel shell yang ingin Anda akses di shell saat ini. Dalam hal ini Anda menggunakan substitusi proses untuk membalikkan pipa:
sumber
Jika Anda berada di negara bagian ini:
Dan Anda menjalankan kode ini:
Anda akan mendapatkan hasil ini:
sumber
for b in "$(git branch)"; do git branch -D $b; done
Tetap sederhana
Cara sederhana untuk mendapatkan nama cabang dalam loop menggunakan skrip bash.
Keluaran:
sumber
Jawaban Googlian, tapi tanpa menggunakan for
sumber
Ini menggunakan pipa git perintah , yang dirancang untuk pembuatan skrip. Ini juga sederhana dan standar.
Referensi: Penyelesaian Git's Bash
sumber