2012-07-02 12 views
5

Ho due repository:Unire due repository (progetto originale e cambiato progetto senza storia)

  • Gephi (grande progetto open source) ospitato su GitHub
  • Progetto della mia azienda sulla base di Gephi

7 mesi fa, quando il nostro progetto è partito, qualcuno ha preso una fotografia istantanea del progetto di Gephi su GitHub e salvarlo in svn aziendale => cambiamento perdita di storia

ora ho deciso di spostare il nostro progetto per git repository e unire le modifiche con il progetto originale

ho repository ora git migrato da svn con git-svn

miei file non ha cronologia delle modifiche al di là del momento in cui il nostro progetto è stato avviato

Posso mappare lo stato iniziale del nostro repository allo stato del repository originale? In altre parole, vorrei iniziare ad applicare le nostre modifiche al repository originale da una revisione specifica.

Aggiornamento:

Oggi ho trovato un altro ostacolo. Schema prima:

enter image description here

  • ramo rosso è il progetto originale

  • <alpha1> e <alpha2> sono commit di plugin per progetto principale (non correlato al codice impegnata in <E' E'' E'''>)

  • in <E'> <E''> <E'''> è stato aggiunto codice dal repository principale del progetto (rosso) <E> (in ciascun commit c ca un terzo del progetto dal <E>)

ho recuperato repository rosso e blu in uno solo. Sul secondo schema ho lo stato desiderato. È possibile farlo? (Per esempio fare da <E' E'' E''> solo commit (<E'>) e poi segno che commettono un fuso da rami <ABCD> e <alpha1 alpha2>)

Grazie Julien per la vostra risposta. Sembra molto utile.

risposta

5

Disclaimer: l'ho testato ora e sembra che funzioni come previsto (presumendo che abbia capito bene, ovviamente). Tuttavia, c'è ancora molto che può andare storto. Provalo assolutamente solo su una copia di lavoro separata del repository del tuo progetto e assicurati di esaminare tutto prima di spostarlo ovunque. Conservare i backup completi delle directory dello stato prima di eseguire questa operazione.

Quindi presumo che tu abbia due repository indipendenti.Il progetto originale (Gephi):

A---B---C---D---E 
       ^HEAD of Gephi 

E il progetto, la cui prima revisione sembra identica alla ultima revisione del progetto originale:

E'---V---W---Y---...---Z 
        ^HEAD of your project 

(possibilmente con alcuni rami, ma che in realtà non importa . qui)

cosa ti piacerebbe avere (se ho capito bene) è:

A---B---C---D---E---V---W---Y---...---Z 

Si potrebbe provare quanto segue. Ancora, fai da solo, albero di lavoro separato e assicurati che sia tutto in ordine prima di inviarlo a qualsiasi repository centrale!

Mentre nella directory del vostro albero di lavoro, prendere le teste e gli oggetti del repository Gephi originale:

git fetch /path/to/original/gephi 

Se non è stato clonato il repository Gephi, si potrebbe anche specificare il github URL invece di un percorso del filesystem locale.

Ciò avrà come risultato la seguente situazione nel vostro albero di lavoro corrente:

A---B---C---D---E 
       ^FETCH_HEAD 

E'---V---W---Y---...---Z 
        ^HEAD 

non abbiamo cambiato molto. Attualmente, i due capi coesistono in modo pacifico e completamente indipendente l'uno dall'altro, ma ora puoi accedere agli oggetti da entrambi i repository e provare a combinarli.

ora vogliamo scartare E'(dovrebbe essere identica a E), e invece fare E il genitore del vostro progetto di primo commit, che è V. A questo scopo, è possibile utilizzare git filter-branch:

git filter-branch -f --parent-filter 'test $GIT_COMMIT = <V> && echo "-p <E>" || cat' 

Sostituire <V> e <E> con gli hash di commit rispettivamente di V ed E. Per scoprirli, puoi fare git log per esaminare i commit del tuo progetto e, dal momento che li abbiamo recuperati, git log FETCH_HEAD per esaminare i commit di Gephi.

Ciò collegare efficacemente V direttamente a E.

Questo dovrebbe anche funzionare se si scopre che la testa (vale a dire l'ultimo commit) del repository originale Gephi non è quello che si basa il progetto su significato che ci sono stati nuovi commit in Gephi che non hai (ancora?) preso cura di te. Basta essere sicuri, ancora una volta di sostituire <E> con l'hash del commit su cui si basano le modifiche, non con la testa.

Al contrario, assicurarsi di sostituire <V> con l'hash della prima modifica apportata. Forse il tuo repository non contiene un E 'identico a E, ma il primo commit contiene già delle modifiche rispetto all'originale. Quindi questo primo hash di commit sarà il tuo <V>, anziché quello successivo.

In sintesi entrambe ultimi paragrafi: il comando di cui sopra dovrebbe funzionare anche se la situazione sembra, per esempio, questo:

A---B---C---D---E---F---G---H---I 
       ^   ^FETCH_HEAD 
       point where your project branched off 

V---W---Y---...---Z 
^    ^HEAD 
first change based on E 

Basta fare in modo di utilizzare l'hash che hanno senso in questo contesto commit.

+0

Ho appena provato questo, e sembra funzionare (così ho aggiornato il mio avviso in cima). Vi consiglio assolutamente di provarlo su un albero di lavoro monouso e di effettuare backup completi. È facile ottenere l'istruzione 'filter-branch' errata o mescolare gli hash! –

+0

Se il progetto locale ha più diramazioni, o se ci sono delle unioni nella cronologia, 'git rebase' non è lo strumento giusto perché linearizzerà la cronologia. Usa invece 'filter-branch'. –

+0

Grazie. Era quello che avevo in origine, ma pensavo che rebase avesse la sintassi più semplice. Ho ripristinato le mie modifiche e ora menziona di nuovo il filtro-ramo. –

1

Sembra che si potrebbe voler indagare grafts (o forse replacements) - questi metodi differiscono da filter-branch e rebase in quanto aggiungono meta-dati per cambiare lo stato visibile del repository, piuttosto che riscrivere la storia per effetto in realtà il cambiamento. Questo è utile quando hai persone che usano i rami esistenti, poiché evita di cambiare la cronologia da sotto di loro.

Nel tuo caso, ti consigliamo di aggiungere un innesto per E', dando E come genitore in più.

+0

Consiglierei 'git replace' su innesti - le sostituzioni sono riferimenti, quindi possono essere sincronizzati tra repository (con un refspec appropriato). –

+0

Sì, è vero in molti casi. Tuttavia, la descrizione del problema suona come il repository git appena iniziato ("ora ho deciso di spostare il nostro progetto [...]/ho ora git repository"), e con un nuovo repository, preferisco le riscritture effettive invece dei metadati aggiuntivi che sarebbe durato fino alla fine dei tempi. –

Problemi correlati