2010-02-11 19 views
56

Tengo un repositorio SVN central al que debo comprometerme, pero tengo una pasión por git (como cualquier otro desarrollador que conozco). El caso es bien conocido.Cómo importar ramas y etiquetas svn en git-svn?

Luego leí sobre git-svn y lo intenté. Dado que no necesito la historia completa, sólo de dos meses o así, lo hice así:

git svn clone -r 34000 -s https://svn.ourdomain.com/svn/repos/Project/SubProject

Subproyecto, como de costumbre, los subdirectorios trunk, tags y branches. Estupendo.

Luego, con el fin de obtener la última revisión, lo hice

git svn rebase

Algunas descargas más tarde, muy bien. Última revisión, registros, etc. Ok, ahora cambiaré a mi rama de características.

$ git branch
* master

$ git branch -r
trunk

$ git branch -a
* master
remotes/trunk

Las preguntas son: ¿Dónde están mis ramas? ¿Hice algo malo? ¿Cómo debo hacer para obtener mis sucursales en el nuevo git repo?

git-svn, dondequiera que haya leído sobre él, manejó sabiamente con ramas y etiquetas, pero el comportamiento no es el esperado. ¡Gracias!

EDIT: Acabo de descubrir que git svn fetch lo hará. Pero obtendrá todas las revisiones, que es algo que no me gustaría.

+2

Bueno, esto no responderá a su pregunta, de ahí el comentario: Cuando se usa git-s vn romperá las características de seguimiento de fusión de Subversion, ya que git-svn no las admite. En mi humilde opinión, este problema por sí solo descalifica a git-svn para un uso serio con un repositorio de subversión. No he encontrado ninguna información sobre si alguna vez se desarrollará esta característica, probablemente no, ya que a las personas les gusta cambiar a un DVCS en lugar de usar dichos hacks. – gimpf

+0

He leído en alguna parte que la transformación de git se fusiona en confirmaciones usando --squash no romperá el seguimiento de fusión de subversión. –

+4

Para el diseño estándar "troncal/ramas/etiquetas", que pareces estar usando, puedes probar ['--stdlayout'] (http://www.kernel.org/pub/software/scm/git/docs /git-svn.html), como en 'git svn clone --stdlayout svn: // ...' - ver http://stackoverflow.com/questions/5361559/what-does-the-stdlayout-do-in -git-svn-clone –

Respuesta

5

Si desea ver sus ramas cuando se hace una rama git después de una importación desde SVN, se debe utilizar la secuencia de comandos de rubí svn2git (and git2svn)

Es mejor que el clon de git svn porque si usted tiene este código en SVN :

trunk 
    ... 
    branches 
    1.x 
    2.x 
    tags 
    1.0.0 
    1.0.1 
    1.0.2 
    1.1.0 
    2.0.0 

git-svn pasarán por la historia comprometerse a construir un nuevo repositorio git.
Importará todas las ramas y etiquetas como ramas SVN remotas, mientras que lo que realmente quieres son ramas nativas de git y objetos de etiqueta git. Así que después de la importación de este proyecto, se llega a:

$ git branch 
    * master 
    $ git branch -a 
    * master 
    1.x 
    2.x 
    tags/1.0.0 
    tags/1.0.1 
    tags/1.0.2 
    tags/1.1.0 
    tags/2.0.0 
    trunk 
    $ git tag -l 
    [ empty ] 

Después svn2git se hace con su proyecto, podrás conseguir este lugar:

$ git branch 
    * master 
    1.x 
    2.x 
    $ git tag -l 
    1.0.0 
    1.0.1 
    1.0.2 
    1.1.0 
    2.0.0 
+0

Pero al hacer esto, ¿no elimino todas las posibilidades de comprometerme con el svn repo? Además, mi pregunta no era esa. No tengo mis ramas. Entonces no es una cuestión de organización de código. –

+0

Utilicé svn2git y trató todas mis ramas y etiquetas como etiquetas ... Así que en otras palabras, cuando estoy haciendo git branch, simplemente me muestra * master. Y cuando estoy haciendo git tag -l me muestra todas las ramas y etiquetas de SVN ... No tiene sentido. Me he perdido algo ? –

+0

@ShariqueAbdullah no estoy seguro. Yo uso SubGit en estos días: http://stackoverflow.com/a/18693798/6309 – VonC

7

Usted dice que usted no ha conseguido sus sucursales en su pago.

Esto probablemente sea un problema con el diseño de su svn repo.

El 'diseño estándar' es:

branches/

tags/

trunk/

Si usted tiene su diseño como esto:

branches/user1/

branches/user2/

Luego, perderá sus ramas cuando haga git svn fetch/clone.

Para solucionar este problema, usted debe dar el argumento

--branches=branches/*/* a git clone.

+0

Pero, ¿y si las sucursales están ubicadas en la raíz, como aquí http://svn.code.sf.net/p/azconvert/code/ ? Las carpetas 'phpport' y' otherfiles' parecen ser ramas. – thorn

63

Necesitará varios pasos.

  1. suministro tronco apropiados, las ramas y etiquetas nombres de las carpetas a buscar SVN repo:

    git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo 
    git svn fetch 
    
  2. Desde etiquetas en SVN son ramas reales, crear etiquetas de git de las ramas de la etiqueta:

    git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/tags | cut -d/-f 3- | 
    while read ref 
    do 
        echo git tag -a $ref -m 'import tag from svn' 
    done 
    
  3. Eliminar etiqueta branches

    git for-each-ref --format="%(refname:short)" refs/remotes/tags | cut -d/-f 2- | 
    while read ref 
    do 
        echo git branch -rd $ref 
    done 
    
  4. Dado que las etiquetas marcadas en el paso anterior apuntan a una confirmación "crear etiqueta", necesitamos derivar etiquetas "reales", es decir, las de los padres de las asignaciones de "crear etiqueta".

    git for-each-ref --format="%(refname:short)" refs/tags | 
    while read ref 
    do 
        tag=`echo $ref | sed 's/_/./g'` # give tags a new name 
        echo $ref -\> $tag 
        git tag -a $tag `git rev-list -2 $ref | tail -1` -m "proper svn tag" 
    done 
    
  5. Todo lo que tenemos que hacer ahora es eliminar las etiquetas antiguas.

+3

El comando "cortar" no funcionaba para la migración de etiquetas, probablemente debido a un resultado diferente del comando "git". Esta línea de comando modificada funcionó para mí: 'git for-each-ref --format ="% (refname: short)% (objectname) "refs/remotes/tags | mientras lee la etiqueta ref; do echo git tag -a $ tag -m \ "Import $ tag desde svn \" $ ref; hecho' –

+6

Lo mismo aquí. También tenga en cuenta que debe eliminar el 'eco' en los comandos una vez que esté satisfecho con lo que haría y desee habilitar el comando real. Terminé con la siguiente línea que marca directamente el padre y usa el mensaje SVN: 'git for-each-ref --format ="% (refname: short)% (objectname) "refs/remotes/tags | corte -d/-f 2- | mientras lee la etiqueta ref; hacer msg = $ (git log --pretty = formato: '% s' -1 $ {ref}); git tag -f -a $ tag -m "$ msg" $ {ref} ^; hecho' – Florian

+0

¿Cuál es la salida de 'git for-each-ref --format = "% (refname: short)" refs/remotes/tags' en su caso? – Vanuan

19

Esto se basa en la respuesta de Vanuan anterior, pero conserva el mensaje del svn etiqueta original en el nuevo git etiqueta.

$ git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/tags \ 
| while read BRANCH REF 
    do 
     TAG_NAME=${BRANCH#*/} 
     BODY="$(git log -1 --format=format:%B $REF)" 

     echo "ref=$REF parent=$(git rev-parse $REF^) tagname=$TAG_NAME body=$BODY" >&2 

     git tag -a -m "$BODY" $TAG_NAME $REF^ &&\ 
     git branch -r -d $BRANCH 
    done 
8

Esto es lo mismo que la respuesta de nicolai.rostov anterior, pero acabo de cambiar la ruta de árbitros He sustituido por refs/remotes/tagsrefs/remotes/origin/tags estoy usando git versión 2.1.1 en cygwin terminal.

$ git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/origin/tags \ 
| while read BRANCH REF 
    do 
     TAG_NAME=${BRANCH#*/} 
     BODY="$(git log -1 --format=format:%B $REF)" 

     echo "ref=$REF parent=$(git rev-parse $REF^) tagname=$TAG_NAME body=$BODY" >&2 

     git tag -a -m "$BODY" $TAG_NAME $REF^ &&\ 
     git branch -r -d $BRANCH 
    done 
0

que tenían el mismo problema - etiquetas y ramas faltaban cuando he especificado la revisión:

$ git svn clone -r 34000 -s https://... 

La solución fue specifiy un rango de revisiones, -r 34000:HEAD:

$ git svn clone -r 34000:HEAD -s https://... 

git mailing list gave me the hint.

Cuestiones relacionadas