2009-03-24 20 views
24

Non riesco a trovare le soluzioni diverse che ho trovato e studiato per il codice esterno di rilevamento . Per non parlare di come applicarli a il mio caso d'uso ...Tracciamento del codice di terze parti con Git

Vorresti essere così gentile da far luce su questo e aiutarmi con il mio caso d'uso specifico ? Quale sarebbe la migliore soluzione per il seguente problema concreto ? (Non ho intenzione di tentativo di generalizzare la mia problema, dal momento che potrei fare ipotesi errate circa roba, soprattutto dato che sono così nuovo con tutto questo ...)

Sto costruendo un sito web in Django (un framework web in Python). Ora, , ci sono molti plugin di terze parti disponibili per l'uso con Django (Django li chiama "app"), che puoi inserire nel tuo progetto. Alcune delle queste app potrebbero richiedere un po 'di modifica per funzionare come mi piace I . Ma se inizi a modificare il codice di terze parti, il tuo problema è quando le versioni più recenti appaiono E allo stesso tempo mantieni le tue modifiche locali.

Quindi, il modo in cui lo farei in Subversion è utilizzando i rami del fornitore. mio layout repository sarebbe simile a questa:

/trunk 
    ... 
    /apps 
    /blog-app 
    ... 
/tags 
    ... 
/branches 
    ... 
/vendor 
    /django-apps 
    /blog-app 
     /1.2 
     /1.3 
     /current 
    /other-app 
     /3.2 
     /current 

In questo caso/trunk/apps/blog-app sarebbero stati SVN copy'd di uno dei i tag nella/vendor/django-apps/blog- app. Dì che era v1.2. E che ora voglio aggiornare la mia versione in trunk alla v1.3. Come puoi vedere vedi, ho già aggiornato/vendor/django-apps/blog-app/corrente (usando svn_load_dirs) e 'taggato' (svn copy) come /vendor/django-apps/blog-app/1.3 . Ora posso aggiornare/trunk/apps/blog-app svn inserendo le modifiche tra /vendor/django-apps/blog-app/1.2 e /vendor/django-apps/blog-app/1.3 on/trunk/apps/blog-app. Questo sarà mantenere le mie modifiche locali. (per le persone sconosciute con questo processo, è descritto nel manuale Subversion: http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html)

Ora voglio fare tutto questo processo in Git. Come posso fare questo?

Permettetemi di ribadire i requisiti:

  • devo essere in grado di inserire il codice esterno in una posizione arbitraria nell'albero
  • devo essere in grado di modificare il codice esterno e mantenere (impegnarsi) questi modifiche nei miei pronti contro termine Git
  • devo essere in grado di aggiornare facilmente il codice esterno, dovrebbe essere rilasciata una nuova versione , pur mantenendo le mie modifiche

extra (per i punti bonus ;-)):

  • Preferibilmente voglio fare questo senza qualcosa di simile svn_load_dirs. I penso che sia possibile tenere traccia delle app e dei loro aggiornamenti direttamente dal loro repository (la maggior parte delle app di Django di terze parti sono conservate in Subversion).Dandomi l'ulteriore vantaggio di essere in grado di visualizzare i singoli messaggi di commit tra le versioni. E il fixing combina più facilmente i conflitti poiché posso gestire un sacco di piccoli commit invece di un commit artificiale creato da svn_load_dirs. Credo che si potrebbe fare questo con svn: gli esterni in Subversion, ma non ho mai lavorato con che prima ...

Una soluzione in cui una combinazione di entrambi i metodi potrebbero essere utilizzati sarebbe ancora più preferibile, poiché potrebbero esserci sviluppatori di app che non usano il controllo del codice sorgente o che non rendono pubblici i loro repository. (Significato sia il comportamento svn_load_dirs-like e il monitoraggio direttamente da un reposity Subversion (o un altro Git))

penso che avrei neanche dovuto usare le sottostrutture, sottomoduli, rebase, rami, ... o una combinazione di questi , ma schiaffeggiami se so quale (i) o come farlo: S

Aspetto con impazienza le tue risposte! Si prega di essere il più dettagliato possibile durante la risposta, poiché ho già avuto difficoltà a comprendere altri esempi trovati online.

Grazie in anticipo

+0

Hai il tuo "aha" -momente nel frattempo? Sto anche cercando questo e sono ancora un po 'insicuro su come farlo. – acme

+0

Beh, ho sicuramente imparato molto di più su Git da quando ho scritto questa domanda e ho anche una migliore comprensione dell'aggiunta di telecomandi e fusione in rami/tag da quei telecomandi. In effetti sto usando qualcosa di simile ora sul posto di lavoro per mantenere aggiornata la nostra installazione Drupal. – hopla

+0

Per quanto riguarda i sottomoduli: non li ho ancora provati, ma ne ho subito il succo. Tuttavia, sembra ancora un sistema molto complicato e soggetto a errori. Allora, come faccio a installare Django ora? Bene, ho avuto anche un po 'di aha in Django e ho imparato molti metodi validi che possono essere usati per estendere le app. Quindi installo app esterne in virtualenv con pip, che è "la strada giusta da fare" comunque. Quindi ho evitato il problema e ho trovato anche una soluzione molto migliore :) – hopla

risposta

27

Ci sono due problemi separati qui:

  1. Come si fa a mantenere forchette locali dei progetti remoti e
  2. Come si fa mantenere una copia dei progetti remoti nel proprio albero?

Il problema 1 è piuttosto semplice da solo. Basta fare qualcosa del tipo:

git clone git://example.com/foo.git 
cd foo 
git remote add upstream git://example.com/foo.git 
git remote rm origin 
git remote add origin ssh://.../my-forked-foo.git 
git push origin 

È quindi possibile lavorare normalmente sul repository biforcuto. Quando si desidera unire le modifiche upstream, eseguire:

git pull upstream master 

Per quanto riguarda il problema 2, un'opzione è utilizzare i sottomoduli. Per questo, cd nel vostro progetto principale, e corro:

git submodule add ssh://.../my-forked-foo.git local/path/for/foo 

Se uso sottomoduli git, che cosa ho bisogno di sapere?

È possibile che i sottomoduli git siano un po 'complicati a volte.Ecco alcune cose da tenere a mente:

  1. Registra sempre il sottomodulo prima di commettere il genitore.
  2. Premere sempre il sottomodulo prima di premere il genitore.
  3. Assicurarsi che il HEAD del sottomodulo punti a un ramo prima di eseguirlo. (Se sei un utente bash, ti consiglio di utilizzare git-completion per inserire il nome del ramo corrente nel tuo prompt.)
  4. Sempre eseguire 'git submodule update' dopo aver cambiato ramo o aver apportato le modifiche.

È possibile aggirare (4) in una certa misura, utilizzando un alias creato da uno dei miei colleghi:

git config --global alias.pull-recursive '!git pull && git submodule update --init' 

... e poi eseguire:

git pull-recursive 

Se i sottomoduli git sono così complicati, quali sono i vantaggi?

  1. È possibile controllare il progetto principale senza verificare i moduli. Questo è utile quando i sottomoduli sono enormi e non ne hai bisogno su determinate piattaforme.
  2. Se hai già incontrato utenti git, è possibile avere più fork del tuo submodule e collegarli con diversi fork del tuo progetto principale.
  3. Un giorno qualcuno potrebbe effettivamente risolvere i sottomoduli git per funzionare in modo più agevole. Le parti più profonde dell'implementazione del sottomodulo sono in realtà abbastanza buone; sono solo gli strumenti di livello superiore che sono rotti.

I sottomoduli git non fanno per me. Cosa succederà?

Se non si desidera utilizzare i sottomoduli git, è possibile esaminare git merge's subtree strategy. Ciò mantiene tutto in un unico repository.

Cosa succede se il repository upstream utilizza Subversion?

Questo è abbastanza facile se si sa come utilizzare git svn:

git svn clone -s https://example.com/foo 
cd foo 
git remote add origin ssh://.../my-forked-foo.git 
git push origin 

quindi impostare una filiale di monitoraggio locale in git.

git push origin master:local-fork 
git checkout -b local-fork origin/local-fork 

Poi, per unire da monte, eseguire:

git svn fetch 
git merge trunk 

(non ho ancora testato questo codice, ma è più o meno come noi manteniamo un modulo con un repository upstream SVN.)

Non utilizzare git svn rebase, perché renderà molto difficile l'utilizzo del sottomodulo git nel progetto principale senza perdita di dati. Basta trattare i rami di Subversion come mirror di sola lettura di upstream e unirli esplicitamente.

Se è necessario per accedere al repository Subversion a monte su un altro computer, provare:

git svn init -s https://example.com/foo 
git svn fetch 

si dovrebbe quindi essere in grado di unire le modifiche da monte come prima.

+0

Il trucco qui sta usando i sottomoduli con git-svn. –

+0

Ryan: Ho aggiunto alcuni esempi di Subversion non testati, basati su un sottomodulo che ho creato pochi giorni fa. Se si rompe, fammelo sapere e lo aggiusterò. Emulatore – emk

+0

: questa è una panoramica molto bella, grazie! Non ho ancora il mio 'aha!' momento, ma penso che dovrò solo provare le cose. Dato che non spingerò indietro le mie modifiche, penso che il metodo di unione dei sottostrati sarebbe la mia migliore scommessa? Posso usarlo in combinazione con git-svn? – hopla

1

io uso sottomoduli git per monitorare le applicazioni riutilizzabili nei miei progetti Django, ma è sorta di disordinato nel lungo periodo.

È complicato per la distribuzione perché non è possibile ottenere un archivio pulito dell'intero albero (con i sottomoduli) utilizzando l'archivio git. Ci sono alcuni trucchi, ma niente di perfetto. Inoltre, il meccanismo di aggiornamento del sottomodulo non è adatto per lavorare con i rami dei sottomoduli.

Potrebbe essere necessario dare un'occhiata a virtualenv e pip, perché avevano alcuni miglioramenti recenti al fine di funzionare con repository esterni.

pip: http://pip.openplans.org/ e lavorare con pip/virtualenv: http://www.b-list.org/weblog/2008/dec/15/pip/

+0

Quanto disordinato diventa? Da dove viene il casino? Potete darmi un URL per questa cosa 'maiale'? Googling per 'git pig' o 'python pig' dà risultati misti (sui serpenti che mangiano maiali ecc.). – hopla

+0

scusate, ho fatto un errore di battitura sul maiale: è pip. –

+0

Ok, grazie. Sarei in grado di apportare modifiche locali usando virtualenv o pip? (e mantieni quelle modifiche quando aggiorni il codice di terze parti) – hopla

3

Mi sono guardato un po 'di più e sono inciampato su Braid. È uno strumento che automatizza le filiali dei distributori in Git. Può usare repository Git o SVN.

Strisciando attraverso la fonte ho scoperto che utilizza la strategia del sottostrato. E sembra renderlo davvero semplice! Inoltre, sembra soddisfare tutte le mie esigenze!

Prima di saltare e usarlo: qualcuno qui ha esperienza con Braid? Mi piacerebbe scoprire i possibili inconvenienti se ce ne sono. Inoltre, se non hai usato Braid, ma hai un po 'di esperienza in Git, cosa ne pensi, a prima vista?

0

Penso che la mia risposta ad altre domande dia esattamente una buona soluzione per il problema qui descritto, senza entrare nel diavolo dei sottomoduli (che ho provato, ma non mi avvicino nemmeno allo svn: l'esterno mi è stato utilizzato per)

Eppure, dare un'occhiata a questa risposta: Do you version control the invidual apps or the whole project or both?

Prima di cancellare la mia risposta ancora una volta, non ero a conoscenza, non ho potuto copiare la mia risposta a un'altra domanda, anche se sono convinto che è utile come risposta. Scusa, ma prova questa risposta, è davvero una buona soluzione. Quindi spero di essere autorizzato a riferire il mio anser ad un'altra domanda.

Problemi correlati