Bagaimana cara menambahkan submodule ke sub-direktori?

310

Saya memiliki repo git ~/.janus/dengan banyak submodul di dalamnya. Saya ingin menambahkan submodule ~/.janus/snipmate-snippets/snippets/, tetapi ketika saya menjalankan git submodule add <[email protected]:...>di snipmate-snippetsdirektori, saya mendapatkan pesan kesalahan berikut:

You need to run this command from the toplevel of the working tree.

Jadi pertanyaannya adalah: Bagaimana cara menambahkan submodule ke snipmate-snippetsdirektori?

Robert Audi
sumber
Pergi ke direktori root dari git repo untuk perintah submodule tidak akan menjadi persyaratan lagi (segera). Lihat jawaban saya di bawah ini
VonC
3
git submodule add -b <branch> <url> <relative_path_4m_root>
parasrish

Jawaban:

439

Anda masuk ~/.janusdan lari:

git submodule add <git@github ...> snipmate-snippets/snippets/

Jika Anda memerlukan informasi lebih lanjut tentang submodula (atau git secara umum) ProGit sangat berguna.

BergmannF
sumber
tampaknya ide yang bagus untuk menambahkan cabang ketika menambahkan jika HEAD mudah dilepaskan: git submodule add -b <branch> <repository> [<submodule-path>]
deann
1
Bagi saya ini yang menyebabkan 'subprojects' already exists in the index (saya menggunakan sub proyek sebagai nama direktori) . Alih-alih yang membantu, adalah jawaban VonC di bawah ini, yaitu melakukan cd subprojects, dan kemudian git submodule add <get@github …>tanpa jalan.
Hi-Angel
83

Perhatikan bahwa mulai git1.8.4 (Juli 2013), Anda tidak perlu kembali ke direktori root lagi.

 cd ~/.janus/snipmate-snippets
 git submodule add <git@github ...> snippets

( Bouke Versteegh berkomentar bahwa Anda tidak harus menggunakan /., seperti dalam snippets/.: snippetssudah cukup)

Lihat komit 091a6eb0feed820a43663ca63dc2bc0bb247bbae :

submodule: jatuhkan persyaratan tingkat atas

Gunakan rev-parse --prefixopsi baru untuk memproses semua jalur yang diberikan ke perintah submodule, menjatuhkan persyaratan bahwa itu harus dijalankan dari tingkat atas repositori.

Karena interpretasi dari URL submodule relatif tergantung pada " remote.origin.url" apakah dikonfigurasi, atau tidak, " " secara eksplisit memblokir URL relatif di " git submodule add" ketika tidak di tingkat atas pohon kerja.

Ditandatangani oleh: John Keeping

Tergantung pada komit 12b9d32790b40bf3ea49134095619700191abf1f

Ini membuat ' git rev-parse' berperilaku seolah-olah itu dipanggil dari subdirektori tertentu dari repositori, dengan perbedaan bahwa setiap path file yang dicetak diawali dengan path lengkap dari atas pohon kerja .

Ini berguna untuk skrip shell di mana kita mungkin ingin ke cdatas pohon kerja tetapi perlu menangani jalur relatif yang diberikan oleh pengguna pada baris perintah.

VONC
sumber
Terima kasih banyak! Saya perhatikan bahwa trailing /.tidak diperlukan, git akan membuat snippet direktori tanpa itu.
Bouke Versteegh
@BoukeVersteegh Menarik. Saya telah memasukkan komentar Anda dalam jawaban untuk lebih banyak visibilitas.
VonC
Saya di git versi 2.7.4 tapi masih saya menerima pesan kesalahan ini Relative path can only be used from the toplevel of the working tree. Saya lakukangit submodule add ../../../functest
FlyingAura
@ user3426358 ya, itu diharapkan: jawaban di atas tentang kemampuan melakukan submit git add dari subfolder dari repo utama, bukan hanya dari folder root-nya. Ini bukan tentang referensi repo jauh submodule dengan jalur relatif. Jika ya, Anda akan mendapatkan pesan kesalahan yang Anda lihat.
VonC
@ user3426358 Dan omong-omong, pesan kesalahan itu (yang Anda lihat: " Relative path can only be used from the toplevel of the working tree") bukan yang dari pertanyaan awal (" You need to run this command from the toplevel of the working tree")
VonC
17

Saya memiliki masalah serupa, tetapi telah melukis diri saya di sudut dengan alat GUI.

Saya memiliki subproyek dengan beberapa file di dalamnya yang sejauh ini saya salin daripada memeriksa git repo mereka sendiri. Saya membuat repo di subfolder, dapat melakukan, mendorong, dll dengan baik. Tetapi dalam repo induk, subfolder tidak diperlakukan sebagai submodule, dan file-nya masih dilacak oleh repo induk - tidak baik.

Untuk keluar dari kekacauan ini, saya harus memberi tahu Git untuk berhenti melacak subfolder (tanpa menghapus file):

proj> git rm -r --cached ./ui/jslib

Lalu saya harus mengatakan bahwa ada submodule di sana (yang tidak dapat Anda lakukan jika ada sesuatu yang saat ini dilacak oleh git):

proj> git submodule add ./ui/jslib

Memperbarui

Cara ideal untuk menangani ini melibatkan beberapa langkah lagi. Idealnya, repo yang ada dipindahkan ke direktori sendiri, bebas dari modul git induk, dikomit dan didorong, dan kemudian ditambahkan sebagai submodule seperti:

proj> git submodule add [email protected]:user/jslib.git ui/jslib

Itu akan mengkloning git repo sebagai submodule - yang melibatkan langkah-langkah kloning standar, tetapi juga beberapa langkah konfigurasi lainnya yang tidak jelas yang git ambil atas nama Anda agar submodule itu berfungsi. Perbedaan yang paling penting adalah bahwa ia menempatkan file .git sederhana di sana, alih-alih direktori .git, yang berisi referensi path ke tempat dir git yang sebenarnya tinggal - umumnya di root proyek induk .git / modules / jslib.

Jika Anda tidak melakukan hal-hal seperti ini mereka akan bekerja dengan baik untuk Anda, tetapi segera setelah Anda berkomitmen dan mendorong orang tua, dan pengembang lain pergi untuk menarik orang tua itu, Anda hanya membuat hidup mereka jauh lebih sulit. Akan sangat sulit bagi mereka untuk meniru struktur yang Anda miliki di mesin Anda selama Anda memiliki dir .git penuh dalam subfolder dari dir yang berisi dir .git sendiri.

Jadi, pindah, dorong, git add submodule, adalah opsi terbersih.

Chris Moschini
sumber
16

Bagi Anda yang berbagi kesukaan aneh saya mengedit file konfigurasi secara manual, menambahkan (atau memodifikasi) berikut ini juga akan melakukan trik.

.git / config (konfigurasi pribadi)

[submodule "cookbooks/apt"]
    url = https://github.com/opscode-cookbooks/apt

.gitmodules (konfigurasi bersama yang dilakukan)

[submodule "cookbooks/apt"]
    path = cookbooks/apt
    url = https://github.com/opscode-cookbooks/apt

Lihat ini juga - perbedaan antara .gitmodules dan spesifikasi submodules di .git / config?

yoniLavi
sumber
2

script bash one-liner untuk membantu fasilitas jawaban Chris di atas, seperti yang telah saya lukis sendiri di sudut juga menggunakan pembaruan Vundle untuk skrip .vim saya. DESTadalah jalur ke direktori yang berisi submodula Anda. Lakukan ini setelah melakukangit rm -r $DEST

DEST='path'; for file in `ls ${DEST}`; do git submodule add `grep url ${DEST}/${file}/.git/config|awk -F= '{print $2}'` ${DEST}/${file}; done

Bersulang

Rick R
sumber