2009-04-28 5 views
131

Comment puis-je synchroniser un référentiel Google Code Subversion auquel je n'ai pas accès en écriture dans un référentiel GitHub?Fourche et synchronisation du référentiel Google Code Subversion dans GitHub

Je souhaite pouvoir développer mes propres fonctionnalités dans mon référentiel Git, mais je souhaite également me synchroniser avec le référentiel Google Code Subversion. Pour récupérer des correctifs du côté du projet Google Code.

Je connaissais git-svn et l'utilisais auparavant pour remonter et descendre dans un dépôt Subversion sur lequel j'avais un contrôle total. Mais je ne sais pas comment rester synchronisé avec un référentiel Google Code Subversion.

Répondre

178

La branche distante de git-svn est à peu près la même que celle d'une télécommande Git standard. Ainsi, dans votre dépôt local, vous pouvez avoir votre clone git-svn et pousser les changements vers GitHub. Git s'en fout. Si vous créez votre clone git-svn et exportez exactement les mêmes modifications sur GitHub, vous aurez un miroir non officiel du référentiel Google Code. Le reste est vanit Git.

git svn clone http://example.googlecode.com/svn -s 
git remote add origin [email protected]:example/example.git 
git push origin master 

Maintenant que vous avez cela, parfois vous devrez synchroniser le dépôt Subversion avec Git. Ça va ressembler à quelque chose comme:

git svn rebase 
git push 

Dans gitk ou autre, cela ressemblerait à quelque chose comme ceci:

o [master][remotes/trunk][remotes/origin/master] 
| 
o 
| 
o 

Et lorsque vous exécutez git svn rebase, vous auriez ceci:

o [master][remotes/trunk] 
| 
o 
| 
o [remotes/origin/master] 
| 
o 
| 
o 

Donc maintenant en cours d'exécution git push pousserait ces commits à GitHub, la branche [distants/origine/maître] là. Et vous reviendrez au scénario dans le premier diagramme artistique ASCII.

Le problème est maintenant, comment travaillez-vous vos changements dans le mélange? L'idée est, vous ne commettez jamais sur la même branche que vous êtes git-svn-rebase-ing et git-pushing. Vous avez besoin d'une branche distincte pour vos modifications. Sinon, vous finirez par rebaser vos modifications sur celles de Subversion, ce qui pourrait contrarier tous ceux qui clonent votre dépôt Git. Suis moi? OK, alors vous créez une branche, appelons-la "fonctionnalités". Et vous faites un commit et le propulsez à GitHub à la branche features. Votre gitk ressemblerait à quelque chose comme ceci:

o [features][remotes/origin/features] 
| 
o 
| 
o [master][remotes/trunk][remotes/origin/master] 
| 
o 

Ici vous avez votre branche deux caractéristiques engage en avance sur la branche Google Code, droit? Alors que se passe-t-il lorsque vous souhaitez intégrer de nouveaux éléments à partir de Google Code? Vous souhaitez exécuter git svn rebase d'abord et obtenez ceci:

      o [features][remotes/origin/features] 
[master][remotes/trunk] o | 
         | o 
         o/
         |/ 
         o[remotes/origin/master] 
         | 
         o 

Si vous git push maître, vous pouvez imaginer le [remotes/origin/master] étant au même point que maître. Mais votre branche de fonctionnalité n'a pas les changements. Vos choix sont maintenant de fusionner le master en fonctionnalités, ou de rebaser les fonctionnalités.Une fusion ressemblerait à ceci:

git checkout features 
git merge master 

      o [features] 
      /| 
     /o [remotes/origin/features] 
[master] o | 
     | o 
     o/
     |/ 
     o 
     | 
     o 

Ensuite, vous poussez les fonctionnalités vers GitHub. J'ai laissé les télécommandes pour maître pour économiser de l'espace, ils seraient au même point que [maître]. L'approche de rebasage est un peu plus mauvaise - vous devriez pousser avec --force car votre poussée ne serait pas une fusion rapide-forward (vous tireriez la branche de caractéristiques sous quelqu'un qui l'avait cloné). Ce n'est pas vraiment acceptable de le faire, mais personne ne peut vous arrêter si vous êtes déterminé. Cela facilite également certaines choses, comme lorsque les patches sont acceptés en amont sous une forme légèrement remaniée. Cela éviterait d'avoir à faire des bêtises avec les conflits, vous pouvez simplement rebasculer --skip les patchs en amont. Quoi qu'il en soit, un rebasage serait comme ceci:

git rebase master features 

     o [features] 
     | 
     o 
     | o [remotes/origin/features] 
[master] o | 
     | o 
     o/
     |/ 
     o 
     | 
     o 

Et vous auriez à git push --force que. Vous pouvez voir pourquoi vous avez besoin de le forcer, l'histoire a un grand vieux schisme des [remotes/origine/caractéristiques] aux nouveaux [caractéristiques] post-rebasage actuel.

Tout cela fonctionne, mais c'est beaucoup d'effort. Si vous allez être un contributeur régulier, le mieux serait de travailler comme ça pendant un moment, d'envoyer des patchs en amont et de voir si vous pouvez obtenir un accès commit à Subversion. A défaut, ne poussez peut-être pas vos changements sur GitHub. Gardez-les locaux et essayez de les faire accepter en amont de toute façon.

+0

Merci pour les excellentes instructions. ('git' noob ici.) Question rapide. Je l'ai fait contre un gros repo SVN et il est sorti à ~ 141 mégaoctets. Je l'ai poussé à github puis je l'ai cloné, et il est sorti à 130 mégaoctets. J'ai couru 'git gc' sur les deux. Qu'est-ce qui pourrait expliquer la différence? – mpontillo

+0

... compris. J'avais besoin de 'git push origin --mirror'. – mpontillo

+0

Travaillé comme un charme, maintenant je dois juste dire à l'original googlecode devs d'utiliser github avec moi: D – electblake

1

Hmm .. Dans mon entreprise, je faisais presque la même chose. Juste avoir à la fois .svn et .git repo dans le même répertoire (vous vérifiez svn repo et créez git repo dans cette copie de travail). Ensuite, en utilisant svn up et git push, c'est ce que j'ai fait. Bien sûr, si vous divergez beaucoup, vous devrez fusionner les choses à la main.

+0

Ja vrai, mais je veux éviter d'avoir les méta-données .svn et j'espérais que git est capable d'utiliser un svn repos comme downstream master – optixx

+0

Donc n'est-ce pas possible utiliser git-svn pour vérifier le repo et git push pour github? –

0

Je ne suis pas sûr de ce qu'il est que vous voulez, mais, bien sûr vous pouvez tirer d'un dépôt subversion et pousser à un dépôt Git de la même copie de travail. Et vous pouvez également retourner au dépôt Subversion. Toutefois, vous ne pouvez pas synchroniser le référentiel GitHub avec le référentiel subversion. De plus, lorsque vous avez des commits dans votre copie de travail qui ne sont pas encore dans le dépôt subversion, vous devrez les rebaser si le dépôt subversion a été mis à jour, ce qui vous obligera à git push --force de commettre GitHub.

10

Un rendez-vous grâce à la synchronisation de Google Code à GitHub est disponible à fnokd.com. L'auteur utilise un serveur distant permanent et un travail cron pour automatiser la synchronisation et conserver le tronc SVN dans une branche GitHub appelée "fournisseur".

2

GitHub prend désormais en charge les projets de subversion importation directe (voir http://help.github.com/import-from-subversion/). Créez simplement un nouveau rapport, puis cliquez sur "Importer à partir de Subversion" dans l'écran "Prochaines étapes". Il ne prend pas en charge la synchronisation supplémentaire, cependant: /.

+0

Cette méthode n'existe plus – magnetik

+0

Utilisez maintenant https://import.github.com/new maintenant. Voir https://help.github.com/articles/importing-from-subversion/. –

15

service svn2github

Le site http://svn2github.com/ fournit un service à fourche tout dépôt SVN accessible au public sur Github (à https://github.com/svn2github/projectname). Je l'ai essayé; en appuyant sur "Faire un miroir" il n'a apparemment rien fait pendant quelques secondes et a affiché le message "erreur", mais cela a effectivement fonctionné. Le nouveau référentiel a été créé, contenant le code du repo SVN.

Vous devez ensuite taper le référentiel qu'il crée et travailler sur votre propre fourche. Vous devez ensuite soumettre vos modifications au projet en amont en utilisant leur bugtracker. En regardant les dépôts existants sous l'utilisateur Github du service (par exemple "svn2github poussé à maîtriser à svn2github/haxe il y a 5 heures"), il semble régulièrement tirer des modifications du référentiel SVN. Il n'y a aucune information sur qui dirige le service sur le site, donc je ne parierais pas qu'il continuerait à fonctionner indéfiniment, mais cela fonctionne pour l'instant (et si jamais il tombe en panne, vous pouvez toujours mettre à jour manuellement votre fork).

Launchpad

Si vous n'êtes pas mis sur l'utilisation de Git et GitHub, une autre alternative est d'utiliser Launchpad.net. Launchpad peut importer automatiquement des dépôts SVN (également CVS) dans une branche bzr personnelle. Pour ce faire, créez un projet Launchpad, puis passez au the new import page, sélectionnez Subversion et entrez l'URL (par exemple, http://projectname.googlecode.com/svn/trunk/). Selon la taille du projet, l'importation initiale peut prendre jusqu'à quelques heures. Les importations subséquentes se dérouleront périodiquement.

Pour plus de documentation, voir VCS Imports on Launchpad Help.

0

Je trouve ces instructions sur le blog de Yu-Jie Lin:

clone d'abord le dépôt Subversion et pousser à la Git:

git svn clone https://foo.googlecode.com/svn/ git-foo 
cd git-foo 
git remote add git-foo [email protected]:username/foo.git 
git push git-foo master 

Après avoir commis dans le dépôt Subversion, exécutez

cd /path/to/git-foo 
git svn fetch 
git svn rebase 
git push git-foo master 
Questions connexes