Come faccio ad aggiungere un sottomodulo a una sottodirectory?


310

Ho un repository git ~/.janus/con un mucchio di sottomoduli. Voglio aggiungere un sottomodulo ~/.janus/snipmate-snippets/snippets/, ma quando corro git submodule add <git@github.com:...>nella snipmate-snippetsdirectory, ricevo il seguente messaggio di errore:

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

Quindi la domanda è: come posso aggiungere un sottomodulo alla snipmate-snippetsdirectory?


Andare alla directory principale di un repository git per i comandi di sottomodulo non sarà più un requisito (presto). Vedi la mia risposta qui sotto
VonC

3
git submodule add -b <branch> <url> <relative_path_4m_root>
Parassita il

Risposte:


439

Vai ~/.janused esegui:

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

Se hai bisogno di maggiori informazioni sui sottomoduli (o git in generale) ProGit è piuttosto utile.


sembra una buona idea aggiungere branch quando si aggiunge altrimenti HEAD si stacca facilmente: git submodule add -b <branch> <repository> [<submodule-path>]
deann

1
Per me questo stava causando 'subprojects' already exists in the index (stavo usando i sottoprogetti come nome della directory) . Invece ciò che ha aiutato, è la risposta del VonC qui sotto, cioè facendo cd subprojects, e quindi git submodule add <get@github …>senza il percorso.
Hi-Angel,

83

Nota che a partire da git1.8.4 (luglio 2013), non dovresti più tornare alla directory principale.

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

( Bouke Versteegh commenta che non devi usare /., come in snippets/.: snippetsè abbastanza)

Vedi commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae :

sottomodulo: elimina il requisito di livello superiore

Utilizzare la nuova rev-parse --prefixopzione per elaborare tutti i percorsi dati al comando submodule, eliminando il requisito che deve essere eseguito dal livello superiore del repository.

Poiché l'interpretazione di un URL del sottomodulo relativo dipende dalla remote.origin.urlconfigurazione o meno di " ", bloccare esplicitamente gli URL relativi in ​​" git submodule add" quando non sono al livello superiore dell'albero di lavoro.

Firmato-fuori-da: John Keeping

Dipende dal commit 12b9d32790b40bf3ea49134095619700191abf1f

Questo fa ' git rev-parse' comportarsi come se fosse stato invocato dalla sottodirectory specificata di un repository, con la differenza che tutti i percorsi di file che stampa sono preceduti dal percorso completo dalla parte superiore dell'albero di lavoro .

Ciò è utile per gli script di shell in cui si potrebbe desiderare cddi accedere all'inizio dell'albero di lavoro ma è necessario gestire i percorsi relativi forniti dall'utente sulla riga di comando.


Grazie mille! Ho notato che il trailing /.non è necessario, git creerà i frammenti di directory senza di essa.
Bouke Versteegh,

@BoukeVersteegh Interessante. Ho incluso il tuo commento nella risposta per una maggiore visibilità.
VonC,

Sono su git versione 2.7.4 ma continuo a ricevere questo messaggio di errore Relative path can only be used from the toplevel of the working tree. Sto facendogit submodule add ../../../functest
FlyingAura il

@ user3426358 sì, ci si aspetta: la risposta sopra os sulla capacità di fare un sottomoduel git aggiungere da qualsiasi sottocartella del repository principale, non solo dalla sua cartella principale. Non si tratta di fare riferimento al repository remoto del sottomodulo con un percorso relativo. In tal caso, verrà visualizzato il messaggio di errore visualizzato.
VonC

@ user3426358 E comunque, quel messaggio di errore (che vedi: " Relative path can only be used from the toplevel of the working tree") non è quello della domanda originale (" You need to run this command from the toplevel of the working tree")
VonC

17

Avevo un problema simile, ma mi ero dipinto in un angolo con gli strumenti della GUI.

Avevo un sottoprogetto con alcuni file che avevo appena copiato, invece di controllare nel loro repository git. Ho creato un repository nella sottocartella, sono stato in grado di eseguire il commit, il push, ecc. Ma nel repository principale la sottocartella non è stata trattata come un sottomodulo e i suoi file erano ancora monitorati dal repository principale - non va bene.

Per uscire da questo casino ho dovuto dire a Git di interrompere il tracciamento della sottocartella (senza cancellare i file):

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

Quindi ho dovuto dire che c'era un sottomodulo lì (che non puoi fare se qualcosa è attualmente monitorato da Git):

proj> git submodule add ./ui/jslib

Aggiornare

Il modo ideale per gestire questo comporta un paio di passaggi in più. Idealmente, il repository esistente viene spostato nella propria directory, libero da qualsiasi modulo genitore git, sottoposto a commit e inviato, quindi aggiunto come sottomodulo come:

proj> git submodule add git@bitbucket.org:user/jslib.git ui/jslib

Ciò clonerà il repository git come sottomodulo, il che comporta i passaggi standard di clonazione, ma anche molti altri passaggi di configurazione più oscuri che Git prende per conto dell'utente per far funzionare quel sottomodulo. La differenza più importante è che posiziona lì un semplice file .git, invece di una directory .git, che contiene un riferimento al percorso in cui vive la directory git reale, generalmente nella radice del progetto genitore .git / modules / jslib.

Se non fai le cose in questo modo funzioneranno bene per te, ma non appena ti impegni e spingi il genitore, e un altro dev va a prenderlo, hai reso la loro vita molto più dura. Sarà molto difficile per loro replicare la struttura che hai sulla tua macchina fintanto che hai una directory .git completa in una sottocartella di una directory che contiene la sua directory .git.

Quindi, spostare, spingere, git aggiungere sottomodulo, è l'opzione più pulita.


16

Per quelli di voi che condividono la mia strana passione per la modifica manuale dei file di configurazione, l'aggiunta (o la modifica) di quanto segue farebbe anche il trucco.

.git / config (configurazione personale)

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

.gitmodules (commit di configurazione condivisa)

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

Vedi anche questa differenza - differenza tra .gitmodules e specificare i sottomoduli in .git / config?


2

script bash one-liner per facilitare la risposta di Chris sopra, dato che mi ero dipinto in un angolo usando anche gli aggiornamenti di Vundle ai miei script .vim. DESTè il percorso della directory contenente i tuoi sottomoduli. Fallo dopo averlo fattogit 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

Saluti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.