46 votes

Gestion des renommages : svn vs. git vs. mercurial

Comment chacun de ces VCS gère-t-il les renommages ?

J'ai trouvé beaucoup d'informations contradictoires affirmant que git suit les LOC (lignes de code) au lieu des fichiers, les renommages n'auraient donc aucune signification pour lui.

2 votes

Bzr s'efforce de faire le bon choix en matière de renommage : markshuttleworth.com/archives/123 . Comment cela se passe-t-il en pratique ? Je ne sais pas. J'utilise principalement git et svn.

3 votes

Et Mark S. s'est efforcé de répandre des rumeurs selon lesquelles les autres VCS ne seraient pas sûrs en matière de renommage...

5 votes

Bzr peut très bien faire cette seule chose correctement, mais je trouve presque tous les autres aspects du système horriblement frustrants. Les seules choses sur lesquelles je travaille qui utilisent bzr l'utilisent à cause de launchpad qui est aussi horriblement frustrant et vous enferme dans leur système de contrôle de révision. C'est la seule chose que Canonical fait qui fait que je ne les aime vraiment pas.

42voto

tonfa Points 8867
  • Git ne suit pas du tout les renommages, mais utilise une heuristique pour les redécouvrir lors des fusions, etc.
  • Mercurial suit les renommages (la version d'origine et le fichier d'origine sont enregistrés) et utilise ces informations lors des fusions. Vous devez donc indiquer explicitement à hg les renommages avec hg mv ou utiliser hg addremove --similarity pour la découverte automatique. Il a également été question d'ajouter des heuristiques pendant la fusion.
  • Svn suit les renommages, mais je ne sais pas s'il les traite correctement lors des fusions (je ne l'ai jamais testé).

2 votes

SVN génère un conflit d'arbre lorsque vous essayez de fusionner vers un fichier qui a été renommé, afin que l'utilisateur puisse décider comment le gérer correctement. Les anciennes versions affichaient simplement un avertissement "skipped" indiquant que la cible de fusion n'existe pas.

6 votes

SVN ne suit pas les renommages. Un renommage dans SVN est enregistré comme un fichier supprimé et un autre ajouté. Le suivi des renommages est prévu pour la version 1.8 de SVN, qui devrait sortir l'année prochaine, mais il reste à voir dans quelle mesure il sera efficace.

4 votes

Le suivi des renommages dans le SVN était prévu pour les versions 1.4, 1.5 et 1.6. Je soupçonne qu'attacher le suivi des renommages à la version 1.8 est juste une façon intelligente de dire pas encore .

23voto

Jakub Narębski Points 87537

Git

Git est différent dans le sens où il ne fait pas renommer le suivi ce qui signifie qu'il n'a pas besoin d'être informé des renommages en utilisant les commandes SCM pour effectuer un renommage (ou exécuter l'autodétection script pour marquer les renommages avant la validation), et qu'il n'enregistre pas ces informations dans le référentiel, mais il fait détection de renommage . Cela signifie qu'il trouve les renommages à l'aide d'un algorithme heuristique basé sur la similarité des noms de fichiers et de leur contenu, à la fois pendant la fusion et pour la comparaison lorsque cela est demandé par le biais de l'option -M (ou configuré à l'aide de l'option diff.renames option de configuration).

Les avantages de cette méthode sont les suivants :

  • les renommages n'ont pas besoin d'être marqués (ou détectés) explicitement : les renommages peuvent provenir d'un patch, ou peuvent être faits via un gestionnaire de fichiers ou une interface graphique.
  • l'algorithme de détection de similarité peut être amélioré, et n'est pas figé au moment du commit comme dans le cas de la détection des renommages pour les marquer avant le commit, et la sauvegarde de cette information dans le dépôt ; il est également plus facile de traiter les erreurs de détection de renommage si elles ne sont pas figées dans l'historique
  • il en découle Git ophilosophie que c'est le contenu qui importe ; voyez comment git blâmer (et ses interfaces graphiques comme "git gui blame") peuvent suivre les mouvements de blocs de code à travers les frontières des fichiers, ce qui est plus générique que les renommages complets de fichiers.
  • le même mécanisme est responsable de la gestion des renommages pendant les fusions ; l'utilisation de la détection des renommages signifie que cela peut être fait pour 3 commits sur lesquels la fusion est finalement basée, et il n'est pas nécessaire de suivre attentivement l'historique, en notant chaque renommage - ou un concept non distribué de nom canonique d'un fichier

Notez que le filtrage de pathspec ne fonctionne pas bien avec la détection des renommages ; si vous voulez suivre l'historique d'un fichier à travers les renommages, utilisez " git log --follow <filename> "

2 votes

Ce "git log --follow" est un joyau caché.

0 votes

Ne pas geler la détection des renommages au moment de la livraison me semble être une arme à double tranchant. Oui, une heuristique améliorée de détection des renommages peut être développée plus tard et améliorer la détection des renommages passés "gratuitement", mais d'un autre côté je pourrais exécuter git log --follow xyz aujourd'hui, et demain, sans que personne ne change xyz entre les deux, et obtenir des résultats différents.

10voto

jammycakes Points 2999

En pratique :

Git détecte les renommages automatiquement. (Par ailleurs, j'ai entendu des affirmations selon lesquelles git peut détecter quand vous déplacez une fonction d'un fichier à un autre. Mes premiers tests semblent indiquer que ce n'est pas le cas, cependant).

Avec Mercurial, vous devez explicitement lui indiquer les renommages, soit par hg mv ou le --similarity option de hg addremove ou l'option "guess renames" de TortoiseHg, ou certains outils comme VisualHg signaleront les renommages pour vous. Si vous voulez utiliser l'approche de Git avec Mercurial, j'ai écrit une version de extension pour détecter les renommages au moment de la livraison mais il est à un stade très expérimental pour le moment.

Subversion ne gère pas les renommages du tout. Il enregistre un renommage comme un fichier supprimé et un autre ajouté. Cela signifie, par exemple, que si Alice modifie un fichier et que Bob le renomme, on obtient un conflit d'arbre. Cela se produit que vous fassiez des branches et des fusions complètes ou simplement svn update . Le suivi des renommages est prévu pour Subversion 1.8, qui devrait sortir l'année prochaine.

6voto

divegeek Points 1754

Vous avez bien entendu, en quelque sorte.

Git opère sur le contenu des fichiers, pas sur les fichiers eux-mêmes, donc les renommages n'ont techniquement aucun sens pour lui. Pour git, un renommage ressemble à la disparition du fichier A et à l'apparition du fichier B avec le même contenu que A. Mais git est en fait assez bon pour savoir quand un fichier a réellement été renommé.

Essayez : renommez un fichier, puis lancez 'git rm oldname' et 'git add newname' pour indiquer à git de mettre en scène les changements, puis lancez 'git status' pour voir ce que git pense faire -- vous verrez qu'il vous indique que le fichier a été renommé. Je ne suis pas sûr que cela signifie quoi que ce soit par la suite, cependant. Regardez un commit avec 'git show' et vous ne verrez aucune mention d'un renommage, juste un tas de lignes enlevées d'un chemin et ajoutées à un autre.

Vous pouvez également utiliser la commande "git mv" pour renommer un fichier. Cela ne change pas la façon dont git perçoit l'opération, il fait simplement "mv oldname newname", "git rm oldname" et "git add newname" en une seule étape.

Pour un aperçu, de Mercurial, voir La réponse de tonfa .

SVN, quant à lui, ne peut pas détecter les renommages mais doit en être informé par la commande 'svn mv'. Cependant, lorsqu'il est informé, il suit les renommages comme des changements de "première classe", de sorte qu'en consultant le journal des modifications plus tard, vous verrez que le changement était un renommage.

Je ne suggérerais pas de choisir un SVN plutôt que git ou mercurial sur la base de cette caractéristique, cependant. Il y a des différences beaucoup plus grandes et plus importantes entre les outils. Je commencerais par décider si vous voulez un système de contrôle de version distribué (git ou mercurial) ou un système de contrôle de version centralisé (svn).

1 votes

Il n'est pas prévu que ce soit une fusillade. J'utilise tous ces outils, merucrial étant utilisé comme mon outil préféré pour les projets personnels où j'ai le choix.

3voto

Josh Lee Points 53741

Une autre chose à propos de git qui n'a pas encore été mentionnée, en plus de l'utilisation de l'heuristique pour déterminer si un renommage a eu lieu :

Si un fichier ou même une arborescence entière de répertoires est renommée, copiée ou déplacée, et que rien en dessous est modifié de quelque manière que ce soit, alors le fichier ou l'arbre est en fait stocké comme le même objet dans le référentiel, et ne prend pas d'espace supplémentaire.

Si vous le modifiez, il est stocké comme un nouvel objet, comme d'habitude.

Je ne suis pas sûr de ce qu'il en est de hg et de svn, mais je soupçonne que leurs architectures orientées sur les modifications les font se comporter différemment dans ce scénario. Cela n'a pas vraiment d'effet sur l'utilisation, sauf que cela pourrait vous donner une raison d'éviter de déplacer ou de copier des arbres énormes dans votre dépôt.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X