SVN: equivalente esterno in Git?


177

Ho due progetti SVN in uso da un altro repository SVN usando svn: externals .

Come posso avere la stessa struttura del layout del repository in Git?


Dovresti esaminare i sottomoduli di Git . Dovrebbe consentire quasi esattamente quello che stai cercando.
Foxxtrot,

7
Qualcuno ha una nuova risposta a questa negli ultimi 4 anni o il mondo di git è lo stesso oggi?
DougW

4
@DougW Sì, ho una nuova risposta qui sotto : git submoduleora posso emulare svn:external(da marzo 2013).
VonC,

Per l'ultima versione di Git, suggerirei di leggere i sottomoduli Git nella documentazione ufficiale di Git.
Bulki S Maslom,

Risposte:


134

Git ha due approcci simili, ma non esattamente equivalenti a svn: externals:

  • Le fusioni di sottostruttura inseriscono il codice del progetto esterno in una sottodirectory separata all'interno del repository. Questo ha un processo dettagliato da configurare e quindi è molto semplice per gli altri utenti, perché viene automaticamente incluso quando il repository viene estratto o clonato. Questo può essere un modo conveniente per includere una dipendenza nel tuo progetto.
    È facile estrarre le modifiche dall'altro progetto, ma è complicato restituire le modifiche. E se l'altro progetto deve fondersi con il tuo codice, le storie dei progetti vengono unite e i due progetti diventano effettivamente uno.

  • Git sottomodules ( manuale ) si collega ad un particolare commit nel repository di un altro progetto, proprio come svn: externals con un-rargomento. I sottomoduli sono facili da configurare, ma tutti gli utenti devono gestire i sottomoduli, che non sono automaticamente inclusi nei checkout (o cloni).
    Sebbene sia facile inoltrare le modifiche all'altro progetto, ciò potrebbe causare problemi se il repository è cambiato. Pertanto, in genere non è appropriato inoltrare le modifiche a un progetto in fase di sviluppo attivo.


17
Cordiali saluti, ora è possibile specificare revisioni specifiche con svn: externals ora (dal 1.5 o 1.6 credo?)
Nate Parsons,

9
Cordiali saluti, i sottomoduli git possono essere gestiti e sottoposti a commit automaticamente. git crea un file .gitmodules che può / deve essere sottoposto a commit proprio come il file .gitignore. Vedere [ git-scm.com/book/en/Git-Tools-Submodules] per ulteriori informazioni.
mikijov,

5
@NateParsons È sempre stato possibile specificare numeri di revisione esatti con svn:externals. Con la revisione 1.5, la sintassi è stata cambiata in un formato più flessibile. È stato aggiunto l'indirizzamento URL relativo.
David W.

@NateParsons ma è possibile omettere le revisioni con i sottomoduli git ...> _>
Trejkaz,

Penso che non sia possibile eseguire il sottomodulo di singoli file come con svn: externals
user1911091

38

Come accennato in " Aggiornamento nuova versione del sottomodulo Git ", è possibile ottenere la stessa funzionalità esterna SVN con i sottomoduli Git 1.8.2:

git config -f .gitmodules submodule.<path>.branch <branch>

Questo è sufficiente affinché un sottomodulo segua un ramo (come nel ULTIMO commit di un ramo remoto di un repository upstream del sottomodulo ). Tutto quello che devi fare è un:

git submodule update --remote

Ciò aggiornerà il sottomodulo.

Maggiori dettagli si trovano nel " git submodulemonitoraggio degli ultimi ".

Per convertire un sottomodulo esistente in uno che tiene traccia di un ramo : vedere tutti i passaggi in " Git sottomoduli: specificare un ramo / tag ".


Puoi fare un checkout parziale come con svn:externals?
nowox,

@nowox Sì, si può avere checkout sparse (git 1.7+ stackoverflow.com/a/2372044/6309 ) associato a moduli ( stackoverflow.com/a/17693008/6309 )
VonC

sfortunatamente tutte le risposte sparse relative al checkout non danno mai alcun esempio :( Proverò a scrivere un esempio Gist per questo ...
nowox,

C'è ancora un problema con questo. Devi ancora ottenere l'intera cronologia di un repository in cui hai solo bisogno di una piccola parte. Nel mio caso è di 100 kB oltre 2 GB. Ovviamente posso usare --depthma non risolve davvero il problema.
nowox,

@nowox È meglio porre una nuova domanda che spieghi esattamente qual è il tuo caso d'uso: non ho idea se il tuo repository da 2 GB è un sottomodulo o un repository principale con sottomodulo e cosa esattamente devi estrarre da esso.
VonC

3

Sono l'autore dello strumento gil (git links)

Ho una soluzione alternativa per lo strumento problem - gil (git links)

Permette di descrivere e gestire dipendenze di repository git complessi.

Inoltre fornisce una soluzione al problema di dipendenza dei sottomoduli ricorsivi git .

Considerare di avere le seguenti dipendenze del progetto: esempio grafico delle dipendenze del repository git

Quindi è possibile definire il .gitlinksfile con la descrizione della relazione dei repository:

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

Ogni riga descrive git link nel seguente formato:

  1. Nome univoco del repository
  2. Percorso relativo del repository (avviato dal percorso del file .gitlinks)
  3. Git repository che verrà usato nel comando git clone Branch repository per il checkout
  4. La riga vuota o iniziata con # non viene analizzata (trattata come commento).

Finalmente devi aggiornare il tuo repository di root:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

Di conseguenza, clonerai tutti i progetti richiesti e li collegherai correttamente.

Se si desidera eseguire il commit di tutte le modifiche in alcuni repository con tutte le modifiche nei repository collegati figlio, è possibile farlo con un singolo comando:

gil commit -a -m "Some big update"

I comandi Pull, push funzionano in modo simile:

gil pull
gil push

Lo strumento Gil (git links) supporta i seguenti comandi:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

Maggiori informazioni sul problema della dipendenza dai sottomoduli ricorsivi git .


1
Dovresti mettere un disclaimer nella parte superiore del post dicendo che sei l'autore di gil.
Daniel Kamil Kozar
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.