Brèves d’experts : et si on utilisait Git pour faciliter le merge dans SVN ?

Dans le monde de la gestion de conf’, il y a ceux qui fonctionnent en mode client / serveur (SVN) et les petits nouveaux qui fonctionnent en mode décentralisé (Git, Mercurial, …). Concrètement, qu’est-ce que ça change ? Avec Git, vous pouvez travailler chez vous le week-end, en mode déconnecté. Super, non ? Mais, ça n’est pas tout ! Il semblerait que Git facilite très largement la gestion des merge. Génial, mais si mon client utilise un serveur SVN et ne veut pas en changer, je suis condamné à continuer de m’arracher les cheveux ? Apparemment, non !

J’ai espionné quelques ODésiens qui en discutaient…

Mathieu :

Soient 2 branches SVN A et B :

  • des commits ont été faits sur A, certains ont été reportés sur B
  • des commits ont été faits sur B, certains ont été reportés sur A

Sachant que tous les commits et reports sont rigoureusement identiques, SVN (ou autre outil affilié) est-il capable de nous déblayer le fastidieux travail pour connaître :

  • les commits faits sur A non reportés sur B ?
  • les commits faits sur B non reportés sur A ?

Benjamin :

SVN diff ? SVN Compare avec Tortoise SVN : http://stackoverflow.com/questions/4675517/compare-files-between-two-branches-in-tortoisesvn ?

Yannick :

En toute rigueur, tu dois exécuter le merge. Avec un bon client (Subclipse dans Eclipse, par exemple), tu obtiens un joli résultat graphique du merge sur ta working copy et tu peux ensuite regarder 1 par 1 les opérations effectuées ainsi que les conflits à résoudre. Si tu n’es pas content de ce merge, tu peux toujours faire un revert pour revenir à l’état initial.

Cela dit, comment ont été effectués tes reports ? Idéalement ils devraient être faits par merge sur une sous-partie et non par recopie manuelle car dans ce cas, le merge A / B va te trouver des conflits sur ces parties même si les fichiers sont identiques (ils ont des révisions différentes).

David :

Pour bien s’en sortir, il faut reporter des « révisions » SVN, en effet, et surtout pas faire les reports à la main.

Mathieu :

C’est bien le problème, on n’est pas beaucoup à faire les reports via des merge. J’ai testé en mergeant 2 branches sur un périmètre raisonnable, et la quantité de trucs à gérer manuellement était déjà énorme. J’ai essayé plusieurs options de merge, style « ignore ancestry » et « allow unversioned obstructions », et à chaque fois, ça s’est fini en revert.

J’ai aussi essayé des trucs plus funky, style exporter en texte les listes des révisions des 2 branches et grepper les commentaires dans tous les sens pour identifier les révisions oubliées à reporter… sans succès.

Cyril de Ninja Squad:

Cette discussion est un vibrant plaidoyer pour passer à Git. Si ce passage est douloureux (il faut bien deux/trois semaines pour se sentir à l’aise), une fois les concepts et les contraintes de SVN désappris, on redécouvre que la gestion des branches peut être simple et efficace.

Par exemple, le fonctionnement intrinsèque de Git est de se préoccuper du contenu des fichiers, et pas des « révisions » : si deux révisions différentes (deux « commits » différents dans la terminologie Git) ont produit le même contenu (en cas de report manuel de code, par exemple), un merge ne produira pas de conflit. Et ce sont des heures de galères avec SVN qui ne sont plus qu’un lointain souvenir!

Sébastien :

Je rejoins largement Cyril sur ce point. De plus, le passage du code d’un dépôt SVN vers un repo Git est maîtrisé et facile à faire, et ce, sans perdre l’historique, évidemment.

Git + 1 ! 😉

Cyrille :

Tu peux utiliser Git sans avoir à changer ton serveur SVN car tu peux utiliser git-svn sur ton ordi, sans impacter les autres développeurs ni le serveur.

Ça va te créer un dépôt Git local, connecté à un SVN à distance. De là, tu peux gérer ton diff avec Git (comme expliqué plus haut, Git gère le contenu, pas les fichiers directement), trouver ce qui diffère, faire les actions associés, et re-pousser le tout (dans SVN, du coup).

Exemple :

$ git svn clone –stdlayout https://mon_depot_svn/ rep_local
$ cd rep_local
$ # différences entre les deux branches
$ git diff remotes/branche_A remotes/branche_B
$ # même choses mais avec les logs
$ git log remotes/branche_A remotes/branche_B
$ # liste les commits qui n’ont pas été reportés sur une branche ou l’autre. Le –oneline c’est pour faire court. Attention c’est bien trois points.
$ git log –cherry-pick –oneline remotes/branche_A…remotes/branche_B

On peut créer des branches locales à partir des remotes de SVN, travailler dessus avec Git (commits, merges, etc.) et les pousser sur SVN à la fin. Pour pousser ensuite avec git-svn, c’est « git svn dcommit » et non « git push ». Tout ceci est expliqué dans la page de manuel de git-svn.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *