2012-03-21 11 views
13

Sto provando a utilizzare il git mirror GCC, documentato here."Impossibile determinare le informazioni SVN a monte dalla cronologia dell'albero di lavoro"

Qualche tempo fa, ho clonato il repository git:

git clone git://gcc.gnu.org/git/gcc.git 

Aggiunto la roba git-svn:

git svn init -Ttrunk --prefix=origin/ svn+ssh://gcc.gnu.org/svn/gcc 

E poi git svn rebase e git svn dcommit ecc tutto ha funzionato bene.

Alcuni mesi dopo, ho fatto vari lavori di sviluppo sui rami Git locali, e sono venuto a commettere più modifiche a monte SVN:

  1. Update dal miror git:

    $ git rebase 
    
  2. Garantire ho l'ultima in assoluto da SVN, ma non funziona:

    $ git svn rebase -v 
    Unable to determine upstream SVN information from working tree history 
    

In qualche modo ho infranto i meta dati! Come sopra, penso di averlo fatto git svn fetch ad un certo punto, per errore, ma non dovrebbe essere dannoso, dovrebbe?

Così, ho cercato di creare un ramo fresco dallo specchio git remote:

$ git branch svntrunk remotes/origin/trunk 
$ git checkout svntrunk 
$ git svn rebase 
Unable to determine upstream SVN information from working tree history 

Una ricerca sul web suggerisce che la storia ramo ha in qualche modo discostato da SVN, ma ho controllato git log ed ogni commettere ha un corrispondente git-svn-id, che sembra smentire ciò, no?

Quindi, ho provato un nuovo clone da git: //gcc.gnu.org/git/gcc.git, e in quel repository git svn rebase funziona correttamente. In che modo i due repository, in cui entrambi hanno avuto git rebase dalla stessa sorgente, hanno una storia diversa? Presumibilmente non possono, e la differenza è nei metadati locali?

Ora, non voglio eliminare il repository in cui ho lavorato (anche se potevo) ed esportare le patch in un altro repository per commettere le sconfitte al punto di avere git-svn in primo luogo. Quindi, come posso ripararlo?

risposta

12

Si dovrebbe essere in grado di farlo con un innesto. L'innesto è progettato per essere utilizzato per introdurre repository legacy è la mia comprensione. Ti consente di digitare manualmente dicendo che alcuni ref hanno un genitore comune.

Come menzionato nei commenti, potrebbe esserci una soluzione più semplice. Questo funzionerebbe se tutto il resto fallisse.

Arrestare il repository git corrente (con git o git-svn) e aggiungere il vecchio repository Git-svn come remoto. Non saranno collegati, in modo gitk sarà simile a questa:

unrelated ancestry

ho avuto un incidente sul posto di lavoro, dove abbiamo avuto un po fare una copia del file system, invece di una copia svn, quindi alcuni dei miei nomi di filiale alludere a quello. Spero che tutto abbia senso comunque. Abbastanza fortunato che mi sia capitato di avere tutte queste immagini e questa storia. Quali sono le probabilità!? Probabilmente abbastanza bene, git-svn è facilmente confuso.

naming branches

Il ramo copied_from è dove copiati. Il graft_ref è dove questo si è verificato. Avevano aggiunto un sacco di file, modificato le proprietà e poi modificato alcuni dei file. Era un po 'un casino.

L'idea generale è di ottenere l'indice della fonte originale, ma il contenuto del file per abbinare le modifiche. Quindi iniziamo nel ramo ref, quindi resettiamo mixed per ottenere l'indice.

$ git checkout graft_ref 
$ git checkout -b graft_parent 
$ git reset --mixed copied_from 

reset mixed

Se non è stata apportare modifiche tra i due rami quando è stato rotto, allora non dovreste preoccuparvi di questo passo.

$ git commit -a -m "svn_branch changes made on svn_trunk filesystem copy" 

Ora dobbiamo eseguire l'innesto vero e proprio. Ho rifilato gli hash qui per la leggibilità.

$ git log -1 --pretty=format:%H graft_ref 
631d3c84e35de98236c3d36c08d14ec92f9c62ae 
$ git log -1 --pretty=format:%H graft_parent 
96a4e87b554e0030035d35ca3aac23e9d71962af 
$ echo "631d3... 96a4e8..." > .git/info/grafts 

grafted

che guarda a come ci si aspetterebbe. Ora abbiamo solo bisogno di ribaltare le modifiche sull'albero. Le mie note mancano per questo, ma penso che questo sia quello che avrei fatto, hehe.

$ git checkout svn_branch/master 
$ git checkout -b consolidate_changes 

consolidated

$ git rebase master 

rebase

Si dovrebbe essere in grado di spingere questi cambiamenti ovunque. Gli innesti non vengono tracciati da Git, quindi il ramo innestato (svn_branch/master e amici) si interromperà di nuovo. È effettivamente un albero morto a meno che tu non faccia di nuovo l'innesto. Per git-svn questo non è un grosso problema perché si limitano a commettere le modifiche e quindi si scollega nuovamente l'origine come copia pulita.

+0

+1, risposta molto bella (da uno dei post del tuo blog, forse ...?). Non sono sicuro che sia direttamente applicabile al problema affrontato (per questo, una soluzione più semplice potrebbe essere più appropriata), ma come procedura applicabile e utilizzabile per l'innesto delle modifiche tra repository in uno stato incoerente, approvo completamente. :) – MrGomez

+1

@MrGomez Spero ci sia una soluzione più semplice. :)) Tutto il resto fallisce, sono abbastanza sicuro che funzionerebbe comunque. –

+0

Quindi, in sostanza, parto da un nuovo repository, inserisco i rami dell'argomento nella cronologia git-svn non rotta al punto giusto tramite un innesto e uso rebase per rendere obsoleto l'innesto. Ho avuto la parte giusta del bastone? – ams

3

Questo è uno scenario abbastanza comune. Anch'io mi sono imbattuto in questo quando ho tentato di sincronizzare i miei nuovi repository Git con il mio vecchio archivio dati supportato da SVN.

Il segreto è mantenere SVN coerente con il ramo master di lavoro in Git. I comandi comuni a tale scopo sono, come già menzionato, git svn rebase (per annullare le modifiche e sincronizzarsi con SVN) e git reset --hard (per eseguire un rollback su una revisione precedente quando l'indice interno si trova in uno stato incoerente). Ci sono volute molte ricerche per sradicare questa procedura per me. (Esegui una copia di backup prima di eseguire una di queste operazioni.)

Il motivo per cui questo sembra accadere è che Git diventa profondamente confuso quando si gestiscono due o più cronologie di modifiche contemporaneamente contro lo stesso ramo di lavoro, che dovrebbe essere HEAD per impostazione predefinita. Se qualcosa cambia nel repository SVN upstream e nelle cronologie delle modifiche a valle che Git non può riconciliare, perde la sua posizione e genera l'errore che hai elencato sopra.

Questo problema è inoltre risolto here. Come menzionato nella risposta principale, ti consigliamo di escludere la possibilità che la tua versione di git debba essere aggiornata e provare le correzioni che hanno raccomandato.

+0

Grazie, ho visto quella domanda, ma come ho git versione 1.7.0.4 non ha risolto il mio problema. Quindi, pensi che se faccio rotolare un ramo in un modo che potrebbe magicamente iniziare a lavorare di nuovo? – ams

+0

@ams Ha fatto per me, almeno! Mi ci sono voluti circa tre giorni di query Google infruttuose prima di trovare questa soluzione per il mio repository. Nel mio caso, avevo commesso modifiche a Git in modo tri-direzionale: all'interno dei suoi file di lavoro, da un repository downstream e in SVN. Non mi è piaciuto un po '. – MrGomez

+0

@ams Vedi anche, questi suggerimenti: http://stackoverflow.com/questions/3095611/git-svn-dcommit-error-unable-to-determine-upstream-svn-information – MrGomez

2

La cosa più semplice che potrebbe funzionare è eseguire git svn fetch. Se si ricollega un repository git esistente a svn, si otterrà questo errore senza una buona ragione quando si git svn rebase. Il problema sottostante è che git-svn fa ipotesi sullo stato del repository che non sempre reggono se non si avvia da un clone svn pulito.

L'opzione successiva è il master di backup git branch master-bkp. E quindi eseguire git reset --hard <way-back>. Quindi eseguire git svn rebase.

Solo se si sta lavorando su un repository git che non si può in alcun modo ricollegare a svn in un modo normale, è possibile provare l'innesto. L'innesto è intelligente e complesso, ma possibile. È anche difficile da fare bene, facile da rovinare, e molto che richiede tempo. Non consigliato come prima opzione.

Problemi correlati