Saya memiliki repositori Git yang memiliki beberapa submodul di dalamnya. Bagaimana saya mendaftar nama semua submodul setelah git submodule init
dijalankan?
The git submodule foreach
perintah bisa menggemakan nama-nama submodule, tapi itu hanya bekerja setelah mereka telah memeriksa yang belum terjadi setelah langkah init. Ada lebih banyak langkah dalam rantai yang perlu terjadi sebelum mereka dapat diperiksa, dan saya tidak ingin harus memasukkan nama-nama submodul ke dalam skrip.
Jadi apakah ada perintah Git untuk mendapatkan semua nama yang terdaftar saat ini, tetapi belum memeriksa submodul?
git
git-submodules
tpg2114
sumber
sumber
git submodule
berperilaku seperti yang saya harapkan hipotetisgit submodule list
untuk berperilaku - Saya hanya tidak pernah berpikir untuk memeriksa apa yang terjadi tanpa argumengit submodule
. (Senang saya menguji tautan itu, karena saya awalnya mengambil tautan 'Bagikan' yang salah!)git submodule list
tidak ada dangit submodule help
tidak membantu (menurut yang terakhir, solusinya,,git submodule
bukan penggunaan yang valid).paths
, tidaknames
dan pecah ketika mereka berisi karakter khusus. Saya mencoba memberikan jawaban untuk kedua nama dan jalur yang harus aman: stackoverflow.com/a/56912913/3215929Jawaban:
Anda bisa menggunakan mekanisme yang sama seperti
git submodule init
menggunakan itu sendiri, yaitu, lihat.gitmodules
. File-file ini menyebutkan setiap jalur submodule dan URL yang dirujuk.Misalnya, dari root repositori,
cat .gitmodules
akan mencetak konten ke layar (dengan asumsi Anda punyacat
).Karena file .gitmodule memiliki format konfigurasi Git, Anda dapat menggunakan konfigurasi git untuk mem-parsing file-file tersebut:
Akan menampilkan semua entri submodule, dan dengan
Anda hanya akan mendapatkan jalur submodule itu sendiri.
sumber
cat .gitmodules
di root repositori ...awk
gagal jika Anda memiliki spasi di jalur submodule.awk
gagal untuk submodula dengan spasi! Perintah harus membacagit config -z --file .gitmodules --get-regexp '\.path$' | sed -nz 's/^[^\n]*\n//p' | tr '\0' '\n'
(Anda perlu modernsed
dengan-z
). Ini gagal untuk jalur dengan Newlines di dalamnya (mereka dapat dibuat dengangit mv
). Jika Anda ingin aman terhadap ini, tinggalkan| tr '\0' '\n'
dan gunakan sesuatu seperti... | while IFS='' read -d '' path; do ...
untuk diproses lebih lanjut dengan bash. Ini membutuhkan bash modern yang mengertiread -d ''
(jangan lupa ruang antara-d
dan''
).Anda dapat menggunakan
git submodule status
atau secara opsionalgit submodule status --recursive
jika Anda ingin menunjukkan submodula bersarang.Dari dokumentasi Git:
sumber
git submodule update --init --recursive
untuk menginisialisasi semua submodule.git
berbasis- asli tanpa bantuan dari bash. Dan solusi ini elegan dalam cara berjalan dengan baik di setiap titik copy pekerjaan (tetapi submodula itu sendiri tentu saja, yang hasilnya langsung berlaku untuk diri mereka sendiri).git submodule
tanpa argumen sama dengangit submodule status
, jadi Anda dapat menyelamatkan diri dengan mengetik 7 karakter ;-)git submodule status --recursive
bekerja, tetapigit submodule --recursive
tidak. 7 karakter itu membelikan Anda sesuatu. Itu tergantung pada kebutuhan Anda.Untuk mengembalikan hanya nama-nama dari submodules terdaftar, Anda dapat menggunakan perintah ini:
Anggap saja itu
git submodule --list
tidak ada.sumber
perl -ne '/^\s*path =\s*(.*)/ and push(@submods, $1); END { print(join("\n", sort(@submods)));}' "$(git rev-parse --show-toplevel)/.gitmodules"
yang dibandingkan dengan jawaban ini (1) berfungsi dari subdirektori mana saja (meskipun tidak di dalam submodule); (2) mengurutkan submodul dengan nama; dan (3) mengabaikan baris komentar dalam .gitmodules.path
mungkin ada dalam nama submodule (git submodule add https://github.com/commercialhaskell/path.git
). Tapi Anda mungkin sudah tahu itu sebelumnya. Jika Anda ingin mengakses.gitconfig
dari mana saja di sebuah meja kerja atau perlu menjalankan ini di--bare
repositori, Anda dapat menggunakan sesuatu sepertigit cat-file -p HEAD:.gitmodules | ...
. Jika Anda perlu merujuk ke file "bertahap", Anda dapat melakukannyagit cat-file -p :.gitmodules | ...
, namun ini membutuhkan gitindex
untuk hadir.Perintah berikut akan mencantumkan submodul:
Outputnya kira-kira seperti ini:
Catatan: Ini membutuhkan Git 2.7.0 atau lebih tinggi.
sumber
git ls-files --stage | grep ^160000
(dari Answer stackoverflow.com/a/29325219 ) tampaknya menghasilkan hasil yang sama, jadi mungkin ini adalah pengganti yang baik jika Anda harus kompatibel dengan yang lebih tua.--
garis ganda disubmodule--helper
Menggunakan:
Ini akan mencantumkan semua submodula dalam repositori Git yang ditentukan.
sumber
git submodule [status]
(catatan yangstatus
tersirat jika dihilangkan, jadi ini sama).fatal: no submodule mapping found in .gitmodules for path 'bla-bla/foo-bar'
. Pertama, Anda harus menghapus semua repositori dalam yang belum dikirim.--recursive
flag, Anda harus secara eksplisit menambahkanstatus
perintah:git submodule status --recursive
berfungsi, tetapigit submodule --recursive
tidak.Saya menggunakan ini:
sumber
Saya perhatikan bahwa perintah yang diberikan dalam jawaban untuk pertanyaan ini memberi saya informasi yang saya cari:
Tidak ditemukan pemetaan submodule di .gitmodule untuk jalur yang bukan submodule
sumber
git ls-files --stage | grep 160000 | perl -ne 'chomp;split;print "$_[3]\n"'
.gimodules
atau apa pun di dalamnya.git/config
. (Saya tidak yakin bagaimana hal itu terjadi, saya mendapat repositori dalam keadaan ini. Itu adalah beberapa kesalahan, jadi solusinya adalahgit rm
.)grep "^160000 "
akan sedikit lebih kuat.Jika Anda tidak keberatan beroperasi hanya pada submodules yang diinisialisasi, Anda dapat menggunakan
git submodule foreach
untuk menghindari penguraian teks.sumber
Kamu bisa memakai:
sumber
test (master)
(nama dengan spasi diikuti oleh tanda kurung), yang merupakan nama submodule yang valid . Perintah juga tidak dapat diperbaiki, karena git mencetakmodule
ataumodule (branch)
. Dan itu bahkan lebih buruk, karena perintah ini tidak porcellain, sehingga output dari perintah dapat berubah di masa depan tanpa pemberitahuan sebelumnya.Saya menggunakan ini:
Output (jalur + versi):
sumber
Untuk membuat daftar semua submodul dengan nama:
git submodule --quiet foreach --recursive 'echo $name'
sumber
Ini bekerja untuk saya:
Ini didasarkan pada artikel hebat ini: Memahami Submodules Git
Itu harus membaca
grep ^160000
.sumber
git ls-files --stage | grep ^160000
tampaknya menghasilkan output yang sama sepertigit submodule--helper list
dari answer stackoverflow.com/a/40877379👍🏼
sumber
.url
kunci, sehingga entri lain mungkin muncul juga (biasanya tidak ada, tapi omong kosong terjadi). Anda harus menggunakan di--local
sini, karena Anda tidak ingin melihat--global
dan--system
pengaturan. Dan yang terakhir untuk dicatat, karena mungkin diabaikan, itu hanya berfungsi untuk submodul, yang sudah ada di.git/config
(seperti setelahgit submodule init
, lihat pertanyaan).git config
memungkinkan untuk menentukan file konfigurasi.Dan
.gitmodules
merupakan file konfigurasi.Jadi, dengan bantuan " gunakan ruang sebagai pembatas dengan perintah cut ":
Itu hanya akan mencantumkan path, satu per submodule yang dideklarasikan.
Seperti yang ditunjukkan Tino dalam komentar :
Sebagai alternatif yang lebih kuat, Tino mengusulkan:
sumber
git submodule add https://github.com/hilbix/bashy.git "sub module"; git mv 'sub module' $'sub\nmodule'
). Lihat komentar saya untuk jawaban yang diterima yang sangat mirip dengan Anda.Dalam versi Git saya [1] , setiap submisi Git memiliki a
name
dan apath
. Mereka tidak harus sama [2] . Mendapatkan keduanya dengan cara yang andal, tanpa memeriksa submodul terlebih dahulu (git update --init
), adalah sedikit trik shell yang sulit.Dapatkan daftar submodule
names
Saya tidak menemukan cara bagaimana mencapai ini menggunakan perintah
git config
apa pungit
. Karenanya kita kembali ke regex on.gitmodules
(super jelek). Tetapi tampaknya agak aman karenagit
membatasi ruang kode yang dimungkinkan untuk submodulenames
. Selain itu, karena Anda mungkin ingin menggunakan daftar ini untuk pemrosesan shell lebih lanjut, solusi di bawah entri yang terpisah denganNULL
-bytes (\0
).Dan dalam skrip Anda:
Catatan :
read -rd ''
membutuhkanbash
dan tidak akan bekerja dengansh
.Dapatkan daftar submodule
paths
Dalam pendekatan saya saya mencoba tidak untuk memproses output dari
git config --get-regexp
denganawk
,tr
,sed
, ... melainkan lulus nol byte dipisahkan kembali kegit config --get
. Ini untuk menghindari masalah dengan baris baru, spasi dan karakter khusus lainnya (misalnya Unicode) dalam submodulepaths
. Selain itu, karena Anda mungkin ingin menggunakan daftar ini untuk pemrosesan shell lebih lanjut, solusi di bawah entri yang terpisah denganNULL
-bytes (\0
).Misalnya, dalam skrip Bash, Anda dapat:
Catatan :
read -rd ''
membutuhkanbash
dan tidak akan bekerja dengansh
.Catatan kaki
[1] Versi Git
[2] Submodule dengan diverging
name
danpath
Siapkan repositori tes:
Pindahkan submodule untuk membuat
name
danpath
menyimpang:Pengujian
Siapkan repositori tes:
.gitmodules
:Dapatkan daftar submodule
names
Dapatkan daftar submodule
paths
sumber
Jika tidak ada
.gitmodules
file, tetapi konfigurasi submodul ada di.git/modules/
:sumber
Berikut adalah cara lain untuk mem-parsing nama-nama submodule Git dari .gitmodules tanpa memerlukan pengaturan IFS. :-)
sumber