Pendekatan naif adalah find dir1 dir2 dir3 -type d -name .git | xargs -I {} dirname {}
, tetapi itu terlalu lambat bagi saya, karena saya memiliki banyak struktur folder yang dalam di dalam repositori git (setidaknya saya berpikir bahwa ini adalah alasannya). Saya telah membaca tentang hal itu yang dapat saya gunakan prune
untuk mencegah penemuan berulang ke direktori setelah menemukan sesuatu, tetapi ada dua hal. Saya tidak yakin bagaimana ini bekerja (maksud saya saya tidak mengerti apa yang saya prune
lakukan walaupun saya sudah membaca halaman manual) dan yang kedua itu tidak akan berfungsi dalam kasus saya, karena itu akan mencegah find
pengulangan ke .git
folder tetapi tidak ke semua folder lain.
Jadi yang sebenarnya saya butuhkan adalah:
untuk semua subdirektori, periksa apakah mereka berisi .git
folder dan jika kemudian berhenti mencari di cabang sistem file ini dan laporkan hasilnya. Akan sempurna jika ini juga akan mengecualikan direktori tersembunyi dari pencarian.
getpof .git
adalah apa yang saya gunakan. github.com/thrig/scripts/blob/master/filesys/getpof.cJawaban:
Oke, saya masih tidak yakin bagaimana ini bekerja, tapi saya sudah mengujinya dan berfungsi.
Saya menantikan untuk membuat hal yang sama lebih cepat.
sumber
-prune
cara ini: Anda mulai akar pohon Anda bergerak turun dan ketika kondisi tertentu berlaku Anda memotong dari seluruh subpohon (seperti nyata "pemangkasan"), sehingga Anda tidak akan melihat lagi node di sub ini .-type d
untuk kondisi manatest -e ...
yang benar dan jika itu benar kami melakukan tindakan-print -prune
yang berarti mencetaknya dan memotong subtree, kan?find . -type d -exec test -e '{}/.git' \; -print -prune | parallel cd "{}" \&\& git pull --rebase
GNUparallel
adalah pengganti yang sangat berguna untukxargs
Kemungkinan Solusi
Untuk GNU
find
dan implementasi lainnya yang mendukung-execdir
:(lihat komentar)
Hal-hal yang sebelumnya dibahas
Solusi jika pemangkasan di bawah
.git
ini sudah cukupJika
-printf '%h'
didukung (seperti halnya GNUfind
), kami tidak perludirname
:Setelah menemukan folder
.git
di jalur saat ini akan mengeluarkannya dan kemudian berhenti mencari lebih jauh ke bawah pohon.Solusi jika seluruh pohon folder harus dipangkas setelah
.git
ditemukanMenggunakan
-quit
jika Andafind
mendukungnya:(Menurut posting rinci oleh Stéphane Chazelas
-quit
ini didukung di GNU dan FreeBSDfind
dan di NetBSD sebagai-exit
.)Lagi dengan
-printf '%h'
jika didukung:Solusi untuk pemangkasan pada tingkat yang sama dengan di mana
.git
folder tersebut beradaLihat bagian "Kemungkinan Solusi" untuk solusi saat ini untuk masalah khusus ini.
(Oh dan jelas solusi menggunakan
xargs
anggap tidak ada baris baru di jalur, jika tidak, Anda akan memerlukan sihir null-byte.)sumber
dir1
berisi dua direktoridirx
dandiry
masing-masing berisi.git
direktori, ini hanya melaporkandirx/.git
dir1/.git
ada, itu masih turundir1/dirx
, yang, berdasarkan pembacaan saya tentang persyaratan OP, tidak diinginkanIdealnya, Anda ingin merayapi pohon direktori untuk direktori yang berisi
.git
entri dan berhenti mencari lebih jauh ke bawah itu (dengan asumsi Anda tidak memiliki repo git lebih lanjut di dalam repo git).Masalahnya adalah bahwa dengan standar
find
, melakukan pemeriksaan semacam ini (bahwa direktori berisi.git
entri) melibatkan pemijahan proses yang mengeksekusitest
utilitas menggunakan-exec
predikat, yang akan menjadi kurang efisien daripada daftar isi beberapa direktori.Pengecualiannya adalah jika Anda menggunakan
find
builtin daribosh
shell (garpu POSIXified dari Bourne shell yang dikembangkan oleh @schily ) yang memiliki-call
predikat untuk mengevaluasi kode dalam shell tanpa harus menelurkan juru bahasa baru:Atau menggunakan
perl
'sFile::Find
:Lagi, tapi lebih cepat dari
zsh
'sprintf '%s\n' **/.git(:h)
(yang turun ke semua direktori non-tersembunyi), atau GNUfind
' sfind . -name '.?*' -prune -o -type d -exec test -e '{}/.git' \; -prune -print
yang berjalan satutest
perintah dalam proses baru untuk setiap direktori non-tersembunyi.sumber
.git
dapat berupa file juga - viagit worktree
-d
s ke-e
.Jika Anda menggunakan loc, Anda dapat menemukan direktori dengan:
Daftar hasil cepat dan pemrosesan lebih lanjut juga mudah.
sumber
locate '*/.git'
Seharusnya cukup.Menggunakan
time
ini, untuk melihat perbedaannya dengan dan tanpa-prune
.Ini didasarkan pada solusi dalam
man find
. Anda dapat mengeditCVS
dansvn
jika tidak diperlukan. isi halaman manual mengikutiDengan direktori proyek berikut dan direktori administratif SCM terkait, lakukan pencarian efisien untuk akar proyek:
Dalam contoh ini,
-prune
cegah keturunan yang tidak perlu ke direktori yang telah ditemukan (misalnya, kami tidak mencariproject3/src
, karena kami sudah menemukanproject3/.svn
), tetapi memastikan direktori saudara (project2
danproject3
) ditemukan.sumber