2010-02-11 6 views
56

J'ai un référentiel SVN central auquel je dois m'engager, mais j'ai une passion pour git (comme tout développeur que je connais). L'affaire est bien connue. Puis j'ai lu à propos de git-svn et l'ai essayé. Depuis que je ne ai pas besoin toute l'histoire, juste de deux mois environ, je l'ai fait comme ceci:Comment importer des branches et des balises svn dans git-svn?

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

Sous-projet avait, comme d'habitude, les sous-répertoires trunk, tags et branches. Génial.

Ensuite, afin d'obtenir la dernière révision, je l'ai fait

git svn rebase

Quelques téléchargements plus tard, une grande. Dernière révision, les journaux, etc. Ok, maintenant je vais passer à ma branche de fonctionnalité. Où sont mes branches:

$ git branch
* master

$ git branch -r
trunk

$ git branch -a
* master
remotes/trunk

Les questions sont? Ai-je fait quelque chose de mal? Comment dois-je faire pour obtenir mes succursales dans le nouveau repo git? Git-svn, où que j'aie lu à ce sujet, a traité avec sagesse les branches et les balises, mais le comportement n'est pas ce que j'attendais. Merci! Je viens d'apprendre que git svn fetch va le faire. Mais il recevra toutes les révisions, ce que je n'aimerais pas.

+2

Eh bien, cela ne répondra pas à votre question, d'où le commentaire: Lors de l'utilisation git-s vn vous casserez les fonctions de suivi de fusion de subversion, car git-svn ne les supporte pas. À mon humble avis ce problème disqualifie git-svn pour une utilisation sérieuse avec un dépôt subversion. Je n'ai pas trouvé d'information pour savoir si cette fonctionnalité sera développée - probablement pas, car les gens aiment passer à un DVCS au lieu d'utiliser de tels hacks. – gimpf

+0

J'ai lu quelque part que la transformation de git fusionne en commits en utilisant --squash ne cassera pas le suivi de fusion de subversion. –

+4

Pour la mise en page standard "trunk/branches/tags" que vous semblez utiliser, vous pouvez essayer ['--stdlayout'] (http://www.kernel.org/pub/software/scm/git/docs /git-svn.html), comme dans 'git svn clone --stdlayout svn: // ...' - voir http://stackoverflow.com/questions/5361559/what-does-the-stdlayout-do-in -git-svn-clone –

Répondre

5

Si vous voulez voir vos branches lorsque vous faites une branche git après une importation de svn, vous devez utiliser le script Ruby svn2git (and git2svn)

Il est meilleur que clone git svn parce que si vous avez ce code dans 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 passera par l'histoire s'engager à construire une nouvelle git.
Il importera toutes les branches et étiquettes en tant que branches SVN distantes, alors que ce que vous voulez vraiment, ce sont les branches locales git-native et les objets tag git. donc après avoir importé ce projet, vous obtiendrez:

$ 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 ] 

Après svn2git est fait avec votre projet, vous obtiendrez ceci:

$ 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

Mais en faisant cela, est-ce que je ne tue pas toutes les possibilités de m'engager dans le svn repo? En outre, ma question n'était pas celle-là. Je n'ai pas mes branches. Donc, ce n'est pas une question d'organisation du code. –

+0

J'ai utilisé svn2git et il a traité toutes mes branches et étiquettes comme des étiquettes ... Donc en d'autres termes, quand je fais la branche git cela me montre * master. Et quand je fais git tag -l il me montre toutes les branches et balises de SVN ... Ça n'a pas de sens. Ai-je manqué quelque chose ? –

+0

@ShariqueAbdullah pas sûr. J'utilise SubGit ces jours-ci: http://stackoverflow.com/a/18693798/6309 – VonC

7

Vous dites que vous ne l'avez pas obtenu vos branches dans votre caisse.

Ceci est probablement un problème avec la disposition de votre svn repo.

La 'mise en page standard' est:

branches/

tags/

trunk/

Si vous avez votre mise en page comme ceci:

branches/user1/

branches/user2/

Ensuite, vous perdrez vos branches si vous faites git svn fetch/clone.

Pour résoudre ce problème, vous devez donner à clone git l'argument

--branches=branches/*/*.

+0

Mais que faire si les branches sont situées dans la racine comme ici http://svn.code.sf.net/p/azconvert/code/ ? Les dossiers 'phpport' et' otherfiles' semblent être des branches. – thorn

63

Vous aurez besoin de plusieurs étapes.

  1. tronc propres

    alimentation, les branches et les tags noms de dossiers et chercher repo svn:

    git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo 
    git svn fetch 
    
  2. Comme balises dans svn sont des branches réelles, créer des tags git de branches tag:

    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. Supprimer les branches de tag

    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. Puisque les balises marquées dans l'étape précédente pointent vers un commit "create tag", nous devons dériver des balises "real", c'est-à-dire des parents de commit "create tag".

    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. Tout ce que nous devons faire maintenant est d'enlever les anciennes étiquettes.

+3

La commande "couper" ne fonctionnait pas pour moi pour la migration des tags, probablement à cause d'une sortie différente de la commande "git". Cette ligne de commande modifiée a fonctionné pour moi: 'git pour chaque ref --format ="% (refname: court)% (objectname) "refs/remotes/tags | tandis que lire l'étiquette ref; echo git tag -a $ tag -m \ "Importer le $ tag de svn \" $ ref; done' –

+6

Même ici. Notez également que vous devez supprimer le 'echo' dans les commandes une fois que vous êtes satisfait de ce qu'il ferait et que vous voulez activer la commande actuelle. Je me suis retrouvé avec la ligne suivante qui étiquette directement le parent et utilise le message SVN: 'git for-each-ref --format ="% (nom ref: court)% (nom de l'objet) "refs/remotes/tags | coupé -d/-f 2- | tandis que lire l'étiquette ref; fais msg = $ (git log --pretty = format: '% s' -1 $ {ref}); git tag -f -a $ tag -m "$ msg" $ {ref} ^; done' – Florian

+0

Quelle est la sortie de 'git pour chaque ref --format ="% (refname: short) "refs/remotes/tags' dans votre cas? – Vanuan

19

Cela tire sur la réponse de Vanuan ci-dessus, mais il conserve le message de l'étiquette svn d'origine dans la nouvelle balise git.

$ 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

C'est le même que la réponse ci-dessus de nicolai.rostov, mais je viens de changer le chemin refs Je l'ai remplacé par refs/remotes/tagsrefs/remotes/origin/tags J'utilise la version git 2.1.1 dans le terminal cygwin.

$ 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

J'ai eu le même problème - les balises et les branches étaient manquantes lorsque je spécifie la révision:

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

Le correctif était de spécifier une plage de révisions, -r 34000:HEAD:

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

Le git mailing list gave me the hint.

Questions connexes