Come realizzare sottomoduli Git poco profondi?


139

È possibile avere sottomoduli superficiali? Ho un superprogetto con diversi sottomoduli, ognuno con una lunga storia, quindi diventa inutilmente grande trascinando tutta quella storia.

Tutto quello che ho trovato è questo thread senza risposta .

Devo solo hackerare git-submodule per implementare questo?


1
" git submodule add/update" ora può clonare i repository sottomoduli in modo superficiale! Vedi la mia risposta qui sotto
VonC

Risposte:


133

Novità nel prossimo git1.4.4 (luglio 2013) :

" git submodule update" può facoltativamente clonare i repository del sottomodulo in modo superficiale.

(E git 2.10 Q3 2016 consente di registrarlo con git config -f .gitmodules submodule.<name>.shallow true.
Vedi la fine di questa risposta)

Vedi commit 275cd184d52b5b81cb89e4ec33e540fb2ae61c1f :

Aggiungi l' --depthopzione ai comandi di aggiunta e aggiornamento di "git submodule", che viene quindi passato al comando clone. Questo è utile quando i sottomoduli sono enormi e non sei veramente interessato ad altro che all'ultimo commit.

Vengono aggiunti test e sono state apportate alcune modifiche di rientro per conformarsi al resto del file di test in "L'aggiornamento del sottomodulo può gestire collegamenti simbolici in pwd".

Firmato-fuori: Fredrik Gustafsson <iveqy@iveqy.com>
Acked-by: Jens Lehmann<Jens.Lehmann@web.de>

Ciò significa che funziona:

git submodule add --depth 1 -- repository path
git submodule update --depth -- [<path>...]

Con:

--depth::

Questa opzione è valida per adde updatecomandi.
Crea un clone 'superficiale' con una cronologia troncata al numero specificato di revisioni.


atwyman aggiunge nei commenti :

Per quanto ne so, questa opzione non è utilizzabile per i sottomoduli che non seguono mastermolto da vicino. Se imposti la profondità 1, submodule updatepuoi sempre riuscire solo se il commit del sottomodulo che desideri è l'ultimo master. Altrimenti ottieni " fatal: reference is not a tree" .

Questo è vero.
Cioè, fino a git 2.8 (marzo 2016). Con 2.8, submodule update --depthc'è ancora una possibilità di successo, anche se SHA1 è direttamente raggiungibile da uno dei repository HEAD remoti.

Vedi commit fb43e31 (24 feb 2016) di Stefan Beller ( stefanbeller) .
Aiutato da: Junio ​​C Hamano ( gitster) .
(Unito da Junio ​​C Hamano - gitster- in commit 9671a76 , 26 febbraio 2016)

sottomodulo: fai di più per recuperare lo sha1 necessario recuperando direttamente sha1

Quando si esamina una modifica che aggiorna anche un sottomodulo in Gerrit, una pratica di revisione comune è quella di scaricare e selezionare la patch localmente per testarla.
Tuttavia, quando lo si verifica localmente, " git submodule update" potrebbe non riuscire a recuperare il sottomodulo sha1 corretto poiché il commit corrispondente nel sottomodulo non fa ancora parte della cronologia del progetto, ma anche solo una modifica proposta.

Se $sha1non faceva parte del recupero predefinito, proviamo a recuperare $sha1direttamente . Alcuni server tuttavia non supportano il recupero diretto di sha1, il che porta git-fetcha un errore rapido.
Possiamo fallire qui perché lo sha1 ancora mancante porterebbe comunque ad un fallimento più tardi nella fase di checkout, quindi fallire qui è il massimo che possiamo ottenere.


MVG sottolinea nei commenti di impegnare fb43e31 (git 2.9, febbraio 2016)

Mi sembra che il commit fb43e31 richieda il commit mancante dall'ID SHA1, quindi le impostazioni uploadpack.allowReachableSHA1InWante uploadpack.allowTipSHA1InWantsul server probabilmente influenzeranno se questo funziona.
Ho scritto un post nella lista di git oggi , sottolineando come l'uso di sottomoduli superficiali potrebbe essere fatto funzionare meglio per alcuni scenari, vale a dire se il commit è anche un tag.
Aspettiamo e vediamo.

Immagino che questo sia un motivo per cui fb43e31 ha reso il recupero per un SHA1 specifico un fallback dopo il recupero per il ramo predefinito.
Tuttavia, nel caso di "--depth 1" penso che avrebbe senso interrompere presto: se nessuno dei riferimenti elencati corrisponde a quello richiesto e chiedere da SHA1 non è supportato dal server, allora non ha senso recuperare nulla, dal momento che non saremo in grado di soddisfare il requisito del sottomodulo in entrambi i casi.


Aggiornamento agosto 2016 (3 anni dopo)

Con Git 2.10 (3 ° trimestre 2016), sarai in grado di farlo

 git config -f .gitmodules submodule.<name>.shallow true

Vedi " Git submodule senza peso extra " per maggiori


Git 2.13 (Q2 2017) aggiunge in commit 8d3047c (19 aprile 2017) di Sebastian Schuberth ( sschuberth) .
(Unita da Sebastian Schuberth - sschuberth- in commit 8d3047c , 20 apr 2017)

un clone di questo sottomodulo verrà eseguito come clone superficiale (con una profondità cronologica di 1)

Tuttavia, Ciro Santilli aggiunge nei commenti (e dettagli nella sua risposta )

shallow = truesulla .gitmodulesinfluenza solo il riferimento tracciati dal capo del telecomando quando si utilizza --recurse-submodules, anche se il bersaglio commit viene puntata da un ramo, e anche se si inserisce branch = mybranchsulla .gitmodulespure.


Git 2.20 (Q4 2018) migliora il supporto del sottomodulo, che è stato aggiornato per essere letto dal BLOB HEAD:.gitmodulesquando il .gitmodulesfile manca dall'albero di lavoro.

Vedi commit 2b1257e , commit 76e9bdc (25 ott 2018) e commit b5c259f , commit 23dd8f5 , commit b2faad4 , commit 2502ffc , commit 996df4d , commit d1b13df , commit 45f5ef3 , commit bcbc780 (05 ott 2018) di Antonio Ospite ( ao2) .
(Unito da Junio ​​C Hamano - gitster- in commit abb4824 , 13 nov 2018)

submodule: supporta la lettura .gitmodulesquando non si trova nell'albero di lavoro

Quando il .gitmodulesfile non è disponibile nell'albero di lavoro, provare a utilizzare il contenuto dall'indice e dal ramo corrente.
Questo riguarda il caso in cui il file fa parte del repository ma per qualche motivo non viene estratto, ad esempio a causa di un checkout scarso.

Ciò consente di utilizzare almeno i git submodulecomandi ' ' che leggono il gitmodulesfile di configurazione senza popolare completamente l'albero di lavoro.

La scrittura su .gitmodulesrichiederà comunque che il file sia stato estratto, quindi verificalo prima di chiamare config_set_in_gitmodules_file_gently.

Aggiungi un check simile anche git-submodule.sh::cmd_add()per anticipare l'eventuale fallimento del git submodule addcomando " " quando .gitmodulesnon è scrivibile in modo sicuro; ciò impedisce al comando di lasciare il repository in uno stato spurio (ad es. il repository del sottomodulo è stato clonato ma .gitmodulesnon è stato aggiornato perché config_set_in_gitmodules_file_gentlynon è riuscito).

Inoltre, poiché config_from_gitmodules()ora accede all'archivio oggetti globale, è necessario proteggere tutti i percorsi di codice che chiamano la funzione dall'accesso simultaneo all'archivio oggetti globale.
Attualmente questo accade solo in builtin/grep.c::grep_submodules(), quindi chiama grep_read_lock()prima di invocare il codice che coinvolge config_from_gitmodules().

NOTA: esiste un raro caso in cui questa nuova funzionalità non funziona ancora correttamente: sottomoduli nidificati senza .gitmodulesnel loro albero di lavoro.


Nota: Git 2.24 (Q4 2019) corregge un possibile segfault durante la clonazione di un sottomodulo superficiale.

Vedi commit ddb3c85 (30 set 2019) di Ali Utku Selen ( auselen) .
(Unito da Junio ​​C Hamano - gitster- in commit 678a9ca , 09 ott 2019)


Git 2.25 (Q1 2020), chiarisce la git submodule updatedocumentazione.

Vedi commit f0e58b3 (24 nov 2019) di Philippe Blain ( phil-blain) .
(Unita da Junio ​​C Hamano - gitster- in commit ef61045 , 05 dic 2019)

doc: menziona che "git submodule update" recupera i commit mancanti

Assistito: Junio ​​C Hamano
Helped: Johannes Schindelin
Firmato-off: Philippe Blain

' git submoduleupdate' recupera i nuovi commit dal telecomando del sottomodulo se non viene trovato lo SHA-1 registrato nel superprogetto . Questo non è stato menzionato nella documentazione.


Avvertenza: con Git 2.25 (Q1 2020), l'interazione tra " git clone --recurse-submodules" e il negozio di oggetti alternativi era mal progettata.

Alla documentazione e al codice è stato insegnato come formulare raccomandazioni più chiare quando gli utenti riscontrano errori.

Vedi commit 4f3e57e , commit 10c64a0 (02 dic 2019) di Jonathan Tan ( jhowtan) .
(Unito da Junio ​​C Hamano - gitster- in commit 5dd1d59 , 10 dic 2019)

submodule--helper: avvisare in caso di errore alternativo fatale

Firmato-fuori: Jonathan Tan
Acked-by: Jeff King

Quando .gitmodulessi clona in modo ricorsivo un superprogetto con alcuni moduli poco profondi definiti al suo interno , quindi si risuona con " --reference=<path>", si verifica un errore. Per esempio:

git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  master
git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  --reference master master2

fallisce con:

fatal: submodule '<snip>' cannot add alternate: reference repository
'<snip>' is shallow

Quando non è possibile aggiungere un supplente calcolato dal supplente del superprogetto, in questo caso o in un altro, consigliare di configurare " submodule.alternateErrorStrategy" l'opzione di configurazione e utilizzare " --reference-if-able" anziché " --reference" durante la clonazione.

Questo è dettagliato in:

Con Git 2.25 (Q1 2020), l'interazione tra "git clone --recurse-submodules" e un negozio di oggetti alternativi era mal progettata.

Doc: spiega submodule.alternateErrorStrategy

Firmato-fuori: Jonathan Tan
Acked-by: Jeff King

Commit 31224cbdc7 (" clone: l'opzione ricorsiva e di riferimento attiva i sostituti del sottomodulo", 17-08-2016, Git v2.11.0-rc0 - unione elencata nel lotto n. 1 ) ha insegnato a Git a supportare le opzioni di configurazione " submodule.alternateLocation" e " submodule.alternateErrorStrategy" su un superprogetto .

Se " submodule.alternateLocation" è configurato su " superproject" su un superprogetto, ogni volta che viene clonato un sottomodulo di quel superprogetto, calcola invece il percorso alternativo analogo per quel sottomodulo dal $GIT_DIR/objects/info/alternatessuperprogetto e lo fa riferimento.

L' submodule.alternateErrorStrategyopzione " " determina cosa succede se tale alternativa non può essere referenziata.
Tuttavia, non è chiaro che il clone procede come se non fosse stata specificata alcuna alternativa quando quell'opzione non è impostata su "die" (come si può vedere nei test in 31224cbdc7 ).
Pertanto, documentarlo di conseguenza.

La documentazione del sottomodulo di configurazione ora include:

submodule.alternateErrorStrategy::

Specifica come trattare gli errori con i supplenti per un sottomodulo come calcolati tramite submodule.alternateLocation.
I valori possibili sono ignore, info, die.
L'impostazione predefinita è die.
Notare che se impostato su ignoreo infoe se si verifica un errore con l'alternativa calcolata, il clone procede come se non fosse stata specificata alcuna alternativa .


2
Caspita che è stato veloce! Grazie per la risposta a proposito. Oh, e --depthdovresti anche discutere;)
Brice,

3
Mi sembra che il commit fb43e31 richieda il commit mancante dall'ID SHA1, quindi le impostazioni uploadpack.allowReachableSHA1InWante uploadpack.allowTipSHA1InWantsul server probabilmente influenzeranno se questo funziona. Ho scritto un post nella lista di git oggi, sottolineando come l'uso di sottomoduli superficiali potrebbe essere fatto funzionare meglio per alcuni scenari, vale a dire se il commit è anche un tag. Aspettiamo e vediamo.
MvG,

2
Con la recente aggiunta dell'opzione shallow in .gitmodules, l' --depth 1opzione funziona per i rami che non seguono da vicino il master?
CMCDragonkai,

2
@CiroSantilli 刘晓波 死 六四 事件 法轮功 Grazie per la precisione e il test. Ho incluso il tuo commento nella risposta per una maggiore visibilità e ho votato a fondo la tua risposta.
VonC,

2
Dalla risposta non è chiaro quale sia il modo attuale di farlo. Inoltre, non è chiaro se tutto ciò è necessario ogni volta che qualcuno clona una nuova copia o queste impostazioni del sottomodulo sparso diventano parte del repository che fa riferimento a questi sottomoduli (ad esempio ogni nuovo clone e aggiornamento del sottomodulo si traducono in checkout sottomodulo sparso)
Pavel P

26

Git 2.9.0 supporta direttamente i sottomoduli del clone superficiale, quindi ora puoi semplicemente chiamare:

git clone url://to/source/repository --recursive --shallow-submodules

2
Questa opzione è la più promettente, ma non riesce a git 2.14.1 del modulo di commit non è monitorata sia da un ramo o tag: stackoverflow.com/a/47374702/895245
Ciro Santilli郝海东冠状病六四事件法轮功

1
@CiroSantilli 刘晓波 死 六四 事件 法轮功 Assicurati che anche il tuo server git sia aggiornato
KindDragon

Grazie, ho testato localmente, senza un server e su GitHub, che non posso aggiornare :-)
Ciro Santilli 19 冠状 病 六四 事件 法轮功

1
Ho lo stesso problema con git 2.20, non funziona quando il sottomodulo non si trova sulla punta del ramo.
Zitrax,

16

Seguendo la risposta di Ryan sono stato in grado di elaborare questo semplice script che scorre attraverso tutti i sottomoduli e li clona superficialmente:

#!/bin/bash
git submodule init
for i in $(git submodule | sed -e 's/.* //'); do
    spath=$(git config -f .gitmodules --get submodule.$i.path)
    surl=$(git config -f .gitmodules --get submodule.$i.url)
    git clone --depth 1 $surl $spath
done
git submodule update

Ricevo fatal: reference is not a tree: 88fb67b07621dfed054d8d75fd50672fb26349dfper ogni sottomodulo
knocte


1
@knocte: ho scritto la mia risposta nel 2010. Le cose sono cambiate. Non puoi aspettarti che tutti mantengano tutte le loro risposte. Ho contrassegnato l'attuale risposta valida come accettata.
Mauricio Scheffer,

13
@knocte Questo è uno dei motivi per cui ho smesso di contribuire a StackOverflow. Le persone hanno queste aspettative non realistiche. Sarebbe un lavoro a tempo pieno mantenere ognuna delle mie 1637 risposte. E poi ci sono anche i commenti, suppongo che dovrei mantenere anche quelli? Dai un'occhiata alle date, ecco a cosa servono. Se leggessi un blog .NET del 2002 con codice usando ArrayList invece di List, lo useresti? Chiederesti all'autore di aggiornare il suo post? Lo stesso principio si applica qui.
Mauricio Scheffer,

1
s / statusquo / progress /
knocte

8

Leggendo la "fonte" di git-submodule, sembra che sia in git submodule addgrado di gestire sottomoduli che hanno già i loro repository presenti. In quel caso...

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
$ git submodule add $remotesub1 $sub1
#repeat as necessary...

Dovrai assicurarti che il commit richiesto sia nel repository sottomodulo, quindi assicurati di impostare un --depth appropriato.

Modifica: potresti riuscire a cavartela con più cloni sottomoduli manuali seguiti da un singolo aggiornamento:

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
#repeat as necessary...
$ git submodule update

5
Ora per git 1.8.0, non è più possibile clonare un repository all'interno di un repository. Quindi questa soluzione non funziona più.
Bohr,

7

Riepilogo del comportamento errato / inatteso / fastidioso di Git 2.14.1

  1. shallow = truein .gitmodulesriguarda solo git clone --recurse-submodulesse la HEADdei punti sottomodulo distanza alla richiesta commit, anche se il bersaglio commit viene puntata da un ramo, e anche se si mette branch = mybranchin .gitmodulespure.

    Script di test locale . Stesso comportamento su GitHub 2017-11, dove HEADè controllato dall'impostazione repository branch predefinita:

    git clone --recurse-submodules https://github.com/cirosantilli/test-shallow-submodule-top-branch-shallow
    cd test-shallow-submodule-top-branch-shallow/mod
    git log
    # Multiple commits, not shallow.
    
  2. git clone --recurse-submodules --shallow-submodulesnon riesce se il commit non è né fa riferimento da un ramo o tag con un messaggio: error: Server does not allow request for unadvertised object.

    Script di test locale . Stesso comportamento su GitHub:

    git clone --recurse-submodules --shallow-submodules https://github.com/cirosantilli/test-shallow-submodule-top-sha
    # error
    

    Ho anche chiesto sulla mailing list: https://marc.info/?l=git&m=151863590026582&w=2 e la risposta è stata:

    In teoria questo dovrebbe essere facile. :)

    In pratica non molto, purtroppo. Questo perché la clonazione otterrà solo l'ultimo suggerimento di un ramo (di solito master). Non esiste alcun meccanismo nel clone per specificare l'esatto sha1 desiderato.

    Il protocollo wire supporta la richiesta di sha1 esatti, quindi dovrebbe essere coperto. (Avvertenza: funziona solo se l'operatore del server abilita uploadpack.allowReachableSHA1InWant che github non ha AFAICT)

    git-fetch permette di recuperare sha1 arbitrario, quindi come soluzione alternativa puoi eseguire un recupero dopo il clone ricorsivo usando "git submodule update" in quanto utilizzerà i recuperi dopo il clone iniziale.

Test TODO: allowReachableSHA1InWant.


Sembra che non esista un modo semplice per eseguire il checkout di un hash di commit HEAD distaccato per il sottomodulo e che abbiano utenti a valle git clone --recursiveche recuperano solo quel commit specifico.
CMCDragonkai,

3

Le posizioni canoniche per i tuoi sottomoduli sono remote? Se è così, stai bene clonandoli una volta? In altre parole, vuoi i cloni poco profondi solo perché stai soffrendo la larghezza di banda sprecata dei frequenti (ri) cloni sottomodulo?

Se vuoi che i cloni superficiali salvino lo spazio su disco locale, la risposta di Ryan Graham sembra un buon modo di procedere. Clonare manualmente i repository in modo che siano poco profondi. Se pensi che sarebbe utile, adattati git submoduleper supportarlo. Invia un'e-mail all'elenco chiedendone (consigli per l'implementazione, suggerimenti sull'interfaccia, ecc.). Secondo me, la gente è abbastanza favorevole ai potenziali collaboratori che vogliono seriamente migliorare Git in modi costruttivi.

Se stai bene facendo un clone completo di ciascun sottomodulo (più i recuperi successivi per tenerli aggiornati), potresti provare a usare l' --referenceopzione di git submodule update(è in Git 1.6.4 e versioni successive) per fare riferimento a negozi di oggetti locali (ad es. creare --mirrorcloni dei repository canonici del sottomodulo, quindi utilizzare --referencenei sottomoduli per puntare a questi cloni locali). Assicurati di leggere git clone --reference/ git clone --sharedprima dell'uso --reference. L'unico problema probabile con i mirror di riferimento sarebbe se finissero mai per recuperare aggiornamenti non rapidi (anche se è possibile abilitare i reflog e espandere le finestre di scadenza per aiutare a conservare eventuali commit abbandonati che potrebbero causare un problema). Non dovresti avere problemi fino a quando

  • non si effettua alcun commit di sottomodulo locale o
  • qualsiasi commit lasciato in sospeso dai non-forward-forward che i repository canonici potrebbero pubblicare non è antenato del commit del tuo sottomodulo locale, oppure
  • sei diligente nel mantenere i tuoi commit del sottomodulo locale in cima a qualunque non-forward-forward possa essere pubblicato nei repository canonici del sottomodulo.

Se vai con qualcosa del genere e c'è qualche possibilità che potresti portare commit dei sottomoduli locali nei tuoi alberi di lavoro, probabilmente sarebbe una buona idea creare un sistema automatizzato che assicuri che gli oggetti critici a cui fanno riferimento i sottomoduli estratti non siano lasciato penzolante nei repository mirror (e se ne viene trovato uno, li copia nei repository che ne hanno bisogno).

E, come git clonedice la manpage, non usare --referencese non capisci queste implicazioni.

# Full clone (mirror), done once.
git clone --mirror $sub1_url $path_to_mirrors/$sub1_name.git
git clone --mirror $sub2_url $path_to_mirrors/$sub2_name.git

# Reference the full clones any time you initialize a submodule
git clone $super_url super
cd super
git submodule update --init --reference $path_to_mirrors/$sub1_name.git $sub1_path_in_super
git submodule update --init --reference $path_to_mirrors/$sub2_name.git $sub2_path_in_super

# To avoid extra packs in each of the superprojects' submodules,
#   update the mirror clones before any pull/merge in super-projects.
for p in $path_to_mirrors/*.git; do GIT_DIR="$p" git fetch; done

cd super
git pull             # merges in new versions of submodules
git submodule update # update sub refs, checkout new versions,
                     #   but no download since they reference the updated mirrors

In alternativa, invece di --reference, è possibile utilizzare i cloni mirror in combinazione con la funzionalità predefinita di hardlinking git cloneutilizzando mirror locali come origine per i sottomoduli. Nei nuovi cloni di super-progetti, fai git submodule init, modifica gli URL del sottomodulo in modo .git/configche puntino ai mirror locali, quindi eseguigit submodule update. Per ottenere i collegamenti fissi, dovrai riconfigurare tutti i sottomoduli di check-out esistenti. Risparmierai la larghezza di banda scaricando una sola volta nei mirror, quindi recuperando localmente da quelli nei sottomoduli estratti. Il collegamento reale risparmierebbe spazio su disco (sebbene i recuperi tendano ad accumularsi e duplicarsi su più istanze degli archivi oggetti dei sottomoduli estratti; è possibile riposizionare periodicamente i sottomoduli estratti dai mirror per recuperare il risparmio di spazio su disco fornito da hardlink).


2

Ho creato una versione leggermente diversa, per quando non funziona al limite, cosa che non tutti i progetti fanno. Le aggiunte standard al sottomodulo non hanno funzionato né lo script sopra. Quindi ho aggiunto una ricerca hash per il tag ref e, se non ne ha uno, ritorna al clone completo.

#!/bin/bash
git submodule init
git submodule | while read hash name junk; do
    spath=$(git config -f .gitmodules --get submodule.$name.path)
    surl=$(git config -f .gitmodules --get submodule.$name.url)
    sbr=$(git ls-remote --tags $surl | sed -r "/${hash:1}/ s|^.*tags/([^^]+).*\$|\1|p;d")
    if [ -z $sbr ]; then
        git clone $surl $spath
    else
        git clone -b $sbr --depth 1 --single-branch $surl $spath
    fi
done
git submodule update 

2

Riferimento a Come clonare repository git con revisione / changeset specifici?

Ho scritto un semplice script che non ha problemi quando il riferimento al sottomodulo è lontano dal master

git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'

Questa istruzione recupererà la versione di riferimento del sottomodulo.

È veloce ma non è possibile eseguire il commit della modifica sul sottomodulo (è necessario recuperarlo prima di https://stackoverflow.com/a/17937889/3156509 )

in toto:

#!/bin/bash
git submodule init
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
git submodule update --recursive

1

Il clone superficiale di un sottomodulo è perfetto perché eseguono un'istantanea a una particolare revisione / changeset. È facile scaricare una zip dal sito Web, quindi ho provato a scrivere uno script.

#!/bin/bash
git submodule deinit --all -f
for value in $(git submodule | perl -pe 's/.*(\w{40})\s([^\s]+).*/\1:\2/'); do
  mysha=${value%:*}
  mysub=${value#*:}
  myurl=$(grep -A2 -Pi "path = $mysub" .gitmodules | grep -Pio '(?<=url =).*/[^.]+')
  mydir=$(dirname $mysub)
  wget $myurl/archive/$mysha.zip
  unzip $mysha.zip -d $mydir
  test -d $mysub && rm -rf $mysub
  mv $mydir/*-$mysha $mysub
  rm $mysha.zip
done
git submodule init

git submodule deinit --all -f cancella l'albero del sottomodulo che consente di riutilizzare lo script.

git submodulerecupera il 40 char sha1 seguito da un percorso che corrisponde allo stesso in .gitmodules. Uso il perl per concatenare queste informazioni, delimitate da due punti, quindi utilizzare la trasformazione variabile per separare i valori in myshae mysub.

Queste sono le chiavi critiche perché abbiamo bisogno di sha1 per il download e il percorso per correlare i urlin .gitmodules.

Data una voce tipica del sottomodulo:

[submodule "label"]
    path = localpath
    url = https://github.com/repository.git

myurli tasti vengono path =quindi visualizzati dopo 2 righe per ottenere il valore. Questo metodo potrebbe non funzionare in modo coerente e richiedere un perfezionamento. Url grep rimuove tutti i .gitriferimenti di tipo rimanenti abbinandoli all'ultimo /e qualsiasi cosa fino a ..

mydirè mysubmeno un finale /nameche verrebbe dalla directory che porta al nome del sottomodulo.

Il prossimo è un wgetcon il formato dell'URL dell'archivio zip scaricabile. Questo potrebbe cambiare in futuro.

Decomprimi il file in mydircui si trova la sottodirectory specificata nel percorso del sottomodulo. La cartella risultante sarà l'ultimo elemento di url- sha1.

Verificare se esiste la sottodirectory specificata nel percorso del sottomodulo e rimuoverla per consentire la ridenominazione della cartella estratta.

mv rinominare la cartella estratta contenente il nostro sha1 nel suo percorso di sottomodulo corretto.

Elimina il file zip scaricato.

Sottomodulo init

Questa è più una prova di concetto WIP piuttosto che una soluzione. Quando funziona, il risultato è un clone superficiale di un sottomodulo in corrispondenza di un changeset specificato.

Se il repository re-home un sottomodulo con un commit diverso, rieseguire lo script per aggiornare.

L'unica volta in cui uno script come questo sarebbe utile è per la costruzione locale non collaborativa di un progetto sorgente.

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.