2012-07-06 27 views
19

Ho usato il seguente comando per clonare svn repo in git e dopo averlo eseguito, vedo alcuni rami spuri.git-svn clone | rami spuri

git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp

git branch -a

*(no branch) 
    master 
    remotes/abc-1.3.x 
    remotes/[email protected] 
    remotes/[email protected] 
    remotes/branch_test_script 
    remotes/tags/modules-1.2 
    remotes/tags/[email protected] 
    remotes/tags/[email protected] 
    remotes/tags/release-1.1 
    remotes/tags/[email protected] 
    remotes/tags/[email protected] 
    remotes/trunk 

rami reali creati in svn erano abc, branch_test_script, moduli e rilascio. Qualcuno può aiutare a capire che cosa sono '[email protected]', '[email protected]' ... '[email protected]' ecc.

Come possiamo sbarazzarci di questi rami spuri/cosa significano?

Grazie,
Gayathri

+0

Ho davvero difficoltà a trovare da dove viene questa denominazione, ma sembra che questi rami vengano creati da commit SVN a cui non è stato trovato più il riferimento dal ramo svn (o tag) su cui erano originariamente creati. Come commit senza riferimento in Git, tranne che è stato possibile recuperare il nome del ramo per il commit. – fork0

+0

@ fork0: Grazie per la risposta. Ma non capisco chiaramente su come i commit senza riferimento possono essere presenti in svn. Come possono essere persi i riferimenti? Puoi condividere le tue opinioni su questo? – crankparty

+0

Non lo so. Forse il manutentore del repository SVN non li ha mai ripuliti (o SVN non ha affatto l'abilità?). Non volevo dire che i riferimenti erano persi, piuttosto qualcuno ha appena iniziato a commettere da un punto precedente nella storia – fork0

risposta

15

tl; dr:

git svn crea questi "@" - rami se un ramo (o tag) è stato creato per una sottodirectory (o per un'altra directory che non è monitorato da git-svn). Ci sarà sempre anche un ramo "normale" con lo stesso nome, ma senza il suffisso "@". Il ramo "@" esiste solo come punto di diramazione per il ramo regolare.


Nota: Ho inviato una patch per questo; una versione modificata di questa spiegazione è ora parte della pagina di manuale ufficiale git svn, come una nuova sezione "MANIPOLAZIONE DEI RAMI SVN" (da Git 1.8.1).


In Subversion, rami e tag sono solo copie di un albero di directory, quindi è possibile (anche se di solito sconsigliato) per creare un ramo da una directory che non si un ramo (o tronco) è. Ad esempio, copiando/trunk/foo in/branches/bar, invece di copiare/trunk (una "sottodirectory branch", per così dire), o copiando una directory che si trova all'esterno della struttura trunk/tags/branches (che è possibile in SVN).

In git, tuttavia, un ramo è sempre per l'intero repository, i rami sottodirectory non esistono. git svn pertanto utilizza una soluzione alternativa. Se rileva un ramo che è stato copiato da una directory che non è tracciata come ramo da git-svn, creerà una nuova cronologia. Ad esempio, per un ramo sottodirectory dove/trunk/foo viene copiato/rami/bar a R1234, si creerà:

  • Un nuovo git commit per ogni revisione SVN r1233 a rovescio (si noti il ​​numero è il ultima revisione prima della creazione del ramo). Gli alberi di questi commit conterranno solo la sottodirectory che è stata ramificata. Quindi, per ogni revisione da r1233 all'indietro, ci saranno solitamente due commit git, uno con l'intero albero (creato quando git-svn ha elaborato la cronologia di trunk) e quelli nuovi.
  • Un ramo fittizio chiamato "bar @ 1233" (nome del ramo @ revisione), che punta al commit creato da r1233 sopra.
  • Un commit da r1234, il commit che ha creato il ramo. Questo commit avrà il ramo sopra come suo (solo) antenato.
  • Un ramo chiamato "bar", che punta al secondo commit.

In questo modo, per il bar ramo sottodirectory, si ottengono due rami in git

  • bar @ 1233, che rappresenta lo stato del repository che il ramo è stato creato da
  • bar, che rappresenta il ramo

Non sono del tutto sicuro del motivo per cui questo ramo fittizio è stato creato. Penso che sia fatto per rappresentare le informazioni su quale revisione è stato diramato il ramo e per avere una cronologia completa per il ramo.


nota che l'intero meccanismo può essere spento utilizzando il flag --no-follow-parent. In tal caso, ogni ramo SVN genererà un ramo git con solo i commit dalla directory del ramo SVN. Ogni ramo sarà scollegato dal resto della cronologia e avrà il proprio commit radice, corrispondente al primo commit nel ramo.

3

ho avuto tali stranamente chiamati rami troppo quando ho clonato il mio SVN pronti contro termine in un repo Git.

Dopo aver esaminato i rami attesi (nel tuo caso modules-1.2, abc-1.3.x, branch_test_script e release-1.1) ho notato che le @revisionnumber rami sono altro che impegna nelle loro succursali prefissati.

Se volete farlo manualmente, aperta gitk sul ramo abc-1.3.x e verificare che [email protected] e [email protected] presentarsi nella storia di quel ramo. In tal caso, è possibile eliminare il rispettivo ramo.

Questo potrebbe essere un po 'macchinoso se si hanno molti rami o molti commit da esplorare.

modo automatico: chiedere git di farlo per voi:

git branch -r --contains [email protected] 

sarà eco (o almeno dovrebbe)

abc-1.3.x 
[email protected] 
[email protected] 

Questo significa che si potrebbe tranquillamente eliminare [email protected] perché è contenuta in abc-1.3.x:

git branch -r -d [email protected] 

A causa della cronologia lineare di SVN, è ovviamente anche contenuto il commit (più recente) 541512.


Nota a margine:
avrete notato che i tag SVN non vengono effettivamente convertiti in tag di Git e rami Git nativi. Ciò potrebbe essere ottenuto utilizzando svn2git per clonare il repository SVN in un repository Git.

+0

Come rimuovere questi rami? C'è qualche parametro che può essere passato a git per ignorare tali commit e non creare rami? – crankparty

+0

Come ho scritto: i rami possono essere cancellati usando 'git branch -r -d '. Non penso che ci sia una bandiera per ottenere che i rami non vengano creati. – eckes

+1

'git-svn' potrebbe creare questi rami" @ "inutilmente, ma esiste un caso importante in cui' abc @ 113346' è ** non ** antenato di 'abc'. Ciò accade se il ramo viene eliminato in sovversione e poi creato di nuovo dalla copia da un altro punto. Inoltre il fatto che 'abc @ 113346' sia un antenato di' abc' non significa che ciò non sia accaduto, potrebbe significare che 'abc' è stato unito a trunk, cancellato (in alcune revisioni superiore a 113346) e un nuovo uno creato al suo posto dal tronco. –