La principale différence est que (comme cela a déjà été dit dans d'autres réponses) CVS est un (ancien) système de contrôle de version centralisé, tandis que Git est distribué.
Mais même si vous utilisez le contrôle de version pour un seul développeur, sur une seule machine (compte unique), il existe quelques différences entre Git et CVS:
Configuration du référentiel . Git stocke le référentiel dans le .git
répertoire du répertoire supérieur de votre projet; CVS nécessite la configuration de CVSROOT, un emplacement central pour stocker les informations de contrôle de version pour différents projets (modules). La conséquence de cette conception pour l'utilisateur est que l'importation de sources existantes dans le contrôle de version est aussi simple que "git init && git add. && git commit" dans Git, alors que c'est plus compliqué dans CVS.
Opérations atomiques . Puisque CVS au début était un ensemble de scripts autour du système de contrôle de version RCS par fichier, les validations (et autres opérations) ne sont pas atomiques dans CVS; si une opération sur le référentiel est interrompue au milieu, le référentiel peut être laissé dans un état incohérent. Dans Git, toutes les opérations sont atomiques: soit elles réussissent dans leur ensemble, soit elles échouent sans aucune modification.
Ensembles de modifications . Les changements dans CVS sont par fichier, tandis que les changements (commits) dans Git ils font toujours référence à l'ensemble du projet. C'est un changement de paradigme très important . Une des conséquences de ceci est qu'il est très facile dans Git de revenir en arrière (créer un changement qui annule) ou d'annuler tout le changement; L'autre conséquence est que dans CVS, il est facile de faire des extractions partielles, alors que c'est actuellement presque impossible dans Git. Le fait que les modifications soient par fichier, regroupées, a conduit à l'invention du format GNU Changelog pour les messages de validation dans CVS; Les utilisateurs de Git utilisent (et certains outils Git s'attendent) à une convention différente, avec une seule ligne décrivant (résumant) les modifications, suivie d'une ligne vide, suivie d'une description plus détaillée des modifications.
Nommer les révisions / numéros de version . Il y a un autre problème lié au fait que dans CVS, les changements sont par fichier: les numéros de version (comme vous pouvez le voir parfois dans l' expansion des mots-clés , voir ci-dessous) comme 1.4 reflètent le nombre de fois que le fichier donné a été modifié. Dans Git, chaque version d'un projet dans son ensemble (chaque commit) a son nom unique donné par SHA-1 id; Habituellement, les 7 à 8 premiers caractères suffisent pour identifier une validation (vous ne pouvez pas utiliser un schéma de numérotation simple pour les versions dans un système de contrôle de version distribué - qui nécessite une autorité de numérotation centrale). Dans CVS pour avoir le numéro de version ou le nom symbolique faisant référence à l'état du projet dans son ensemble, vous utilisez des balises; la même chose est vraie dans Git si vous voulez utiliser un nom comme 'v1.5.6-rc2' pour une version d'un projet ... mais les balises dans Git sont beaucoup plus faciles à utiliser.
Branchement facile . Les branches de CVS sont à mon avis trop compliquées et difficiles à gérer. Vous devez étiqueter les branches pour avoir un nom pour toute une branche de référentiel (et même cela peut échouer dans certains cas, si je me souviens bien, à cause de la gestion par fichier). Ajoutez à cela le fait que CVS ne dispose pas de suivi des fusions , vous devez donc vous souvenir, ou marquer manuellement les fusions et les points de branchement, et fournir manuellement les informations correctes pour que "cvs update -j" fusionne les branches, et cela permet de créer des branches. être inutile difficile à utiliser. Dans Git, créer et fusionner des branches est très simple; Git se souvient de toutes les informations requises par lui-même (donc fusionner une branche est aussi simple que "git merge branchname ") ... il le fallait, car le développement distribué conduit naturellement à plusieurs branches.
Cela signifie que vous pouvez utiliser des branches de rubrique , c'est-à-dire développer une fonctionnalité distincte en plusieurs étapes dans une branche de fonctionnalité distincte.
Renommer (et copier) le suivi . Les renommages de fichiers ne sont pas pris en charge dans CVS et le changement de nom manuel peut briser l'historique en deux ou conduire à un historique invalide où vous ne pouvez pas récupérer correctement l'état d'un projet avant de le renommer. Git utilise une détection heuristique de changement de nom, basée sur la similitude du contenu et du nom de fichier (cette solution fonctionne bien en pratique). Vous pouvez également demander la détection de la copie de fichiers. Cela signifie que:
- lors de l'examen du commit spécifié, vous obtiendrez des informations indiquant qu'un fichier a été renommé,
- la fusion prend correctement en compte les renommés (par exemple si le fichier n'a été renommé que dans une branche)
- "git blame", le (meilleur) équivalent de "cvs annotate", un outil pour afficher l'historique ligne du contenu d'un fichier, peut suivre le mouvement du code également à travers les renommages
Fichiers binaires . CVS n'a qu'un support très limité pour les fichiers binaires (par exemple, les images), obligeant les utilisateurs à marquer les fichiers binaires explicitement lors de l'ajout (ou plus tard en utilisant "cvs admin", ou via des wrappers pour le faire automatiquement en fonction du nom de fichier), pour éviter de modifier fichier binaire via la conversion de fin de ligne et l'expansion des mots clés. Git détecte automatiquement les fichiers binaires en fonction du contenu de la même manière que CNU diff et d'autres outils le font; vous pouvez remplacer cette détection en utilisant le mécanisme gitattributes. De plus, les fichiers binaires sont sûrs contre les malformations irrécupérables grâce à la valeur par défaut de 'safecrlf' (et au fait que vous devez demander une conversion de fin de ligne, bien que cela puisse être activé par défaut en fonction de la distribution), et ce mot-clé (limité) l'expansion est un 'opt-in' strict dans Git.
Expansion des mots clés . Git propose un ensemble très, très limité de mots-clés par rapport à CVS (par défaut). Ceci est dû à deux faits: les changements dans Git sont par référentiel et non par fichier, et Git évite de modifier les fichiers qui n'ont pas changé lors du passage à une autre branche ou du retour à un autre point de l'historique. Si vous voulez incorporer le numéro de révision en utilisant Git, vous devez le faire en utilisant votre système de construction, par exemple l'exemple suivant de script GIT-VERSION-GEN dans les sources du noyau Linux et dans les sources Git.
Modification des engagements . Parce que dans un VCS distribué tel que Git, l'acte de publication est distinct de la création d'un commit, on peut changer (éditer, réécrire) une partie non publiée de l'historique sans gêner les autres utilisateurs. En particulier, si vous remarquez une faute de frappe (ou une autre erreur) dans le message de commit, ou un bogue dans commit, vous pouvez simplement utiliser "git commit --amend". Ce n'est pas possible (du moins pas sans piratage intensif) dans CVS.
Plus d'outils . Git propose bien plus d'outils que CVS. Un des plus importants est " git bisect " qui peut être utilisé pour trouver un commit (révision) qui a introduit un bogue; si vos commits sont petits et autonomes, il devrait être assez facile de découvrir où se trouve le bogue.
Si vous collaborez avec au moins un autre développeur, vous trouverez également les différences suivantes entre Git et CVS:
Commit before merge Git utilise commit-before-merge plutôt que, comme CVS, merge-before-commit (ou update-then-commit ). Si pendant que vous éditiez des fichiers, prépariez la création d'un nouveau commit (nouvelle révision), quelqu'un d'autre a créé un nouveau commit sur la même branche et qu'il se trouve maintenant dans le référentiel, CVS vous oblige à mettre d'abord à jour votre répertoire de travail et à résoudre les conflits avant de vous autoriser à commettre. Ce n'est pas le cas avec Git. Vous commencez par valider, en enregistrant votre état dans le contrôle de version, puis vous fusionnez d'autres modifications du développeur. Vous pouvez également demander à l'autre développeur de procéder à la fusion et de résoudre les conflits.
Si vous préférez avoir un historique linéaire et éviter les fusions, vous pouvez toujours utiliser le workflow commit-merge- recommit via "git rebase" (et "git pull --rebase"), qui est similaire à CVS en ce que vous rejouez vos modifications en haut de l'état mis à jour. Mais vous vous engagez toujours en premier.
Pas besoin de référentiel central Avec Git, il n'est pas nécessaire d'avoir un emplacement central unique où vous validez vos modifications. Chaque développeur peut avoir son propre référentiel (ou de meilleurs référentiels: un référentiel privé dans lequel il / elle fait du développement, et un référentiel public où il / il publie la partie qui est prête), et ils peuvent extraire / récupérer les uns des autres référentiels, en mode symétrique. D'un autre côté, il est courant pour des projets plus importants d'avoir un référentiel central socialement défini / nominé à partir duquel tout le monde tire (à partir duquel les changements).
Enfin, Git offre beaucoup plus de possibilités lorsqu'une collaboration avec un grand nombre de développeurs est nécessaire. Ci-dessous, il y a des différences entre CVS dans Git pour différentes étapes d'intérêt et de position dans un projet (sous contrôle de version en utilisant CVS ou Git):
lurker . Si vous souhaitez uniquement obtenir les dernières modifications d'un projet ( pas de propagation de vos modifications ) ou faire du développement privé (sans contribuer aux projets originaux); ou vous utilisez des projets étrangers comme base de votre propre projet (les changements sont locaux et cela n'a pas de sens de les publier).
Git prend en charge ici l' accès en lecture seule anonyme non authentifié via un git://
protocole efficace personnalisé , ou si vous êtes derrière le blocage du pare-feu DEFAULT_GIT_PORT
(9418), vous pouvez utiliser le HTTP pur.
Pour CVS, la solution la plus courante (si je comprends bien) pour l'accès en lecture seule est le compte invité pour le protocole «pserver» sur CVS_AUTH_PORT
(2401), généralement appelé «anonyme» et avec un mot de passe vide. Les informations d'identification sont stockées par défaut dans le $HOME/.cvspass
fichier, vous ne devez donc les fournir qu'une seule fois; c'est quand même un peu de barrière (vous devez connaître le nom du compte invité, ou faire attention aux messages du serveur CVS) et de la gêne.
développeur frange (contributeur feuille) . Une façon de propager vos modifications dans OSS consiste à envoyer des correctifs par e-mail . C'est la solution la plus courante si vous êtes (plus ou moins) développeur accidentel, envoyez un seul changement ou un seul bug. BTW. l'envoi de correctifs peut se faire via un tableau de révision (système de révision des correctifs) ou des moyens similaires, pas seulement par e-mail.
Git propose ici des outils qui aident dans ce mécanisme de propagation (publication) à la fois pour l'expéditeur (client) et pour le mainteneur (serveur). Pour les personnes qui souhaitent envoyer leurs modifications par e-mail, il existe un outil " git rebase " (ou "git pull --rebase") pour rejouer vos propres modifications en plus de la version amont actuelle, afin que vos modifications soient au-dessus de la version actuelle (sont fraîches ), et " git format-patch " pour créer un e-mail avec message de validation (et auteur), changement sous la forme d'un format de diff unifié (étendu) (plus diffstat pour une révision plus facile). Le mainteneur peut transformer un tel e-mail directement en commit préservant toutes les informations (y compris le message de commit) en utilisant " git am ".
CVS n'offre pas de tels outils: vous pouvez utiliser "cvs diff" / "cvs rdiff" pour générer des changements, et utiliser le patch GNU pour appliquer les changements, mais pour autant que je sache, il n'y a aucun moyen d'automatiser l'application du message de validation. CVS était destiné à être utilisé à la manière du client <-> serveur ...
lieutenant . Si vous êtes le mainteneur d'une partie distincte d'un projet (sous-système), ou si le développement de votre projet suit le flux de travail «réseau de confiance» utilisé dans le développement du noyau Linux ... ou simplement si vous avez votre propre référentiel public, et les changements que vous que vous souhaitez publier sont trop volumineux pour être envoyés par e-mail en tant que série de correctifs , vous pouvez envoyer une demande d'extraction au (principal) responsable du projet.
Il s'agit d'une solution spécifique aux systèmes de contrôle de version distribués , donc bien sûr CVS ne prend pas en charge ce type de collaboration. Il existe même un outil appelé "git request-pull" qui aide à préparer le courrier électronique à envoyer au responsable avec une demande d'extraire de votre référentiel. Grâce à "git bundle", vous pouvez utiliser ce mécanisme même sans avoir de référentiel public, en envoyant un ensemble de modifications par e-mail ou sneakernet. Certains sites d'hébergement Git comme GitHub prennent en charge la notification que quelqu'un travaille (a publié du travail) sur votre projet (à condition qu'il utilise le même site d'hébergement Git), et pour PM-ing une sorte de pull request.
développeur principal , c'est-à-dire quelqu'un qui publie directement ses modifications (dans le référentiel principal / canonique). Cette catégorie est plus large pour les systèmes de contrôle de version distribués, car avoir plusieurs développeurs avec un accès en écriture au référentiel central n'est pas seulement un flux de travail possible (vous pouvez avoir un seul responsable qui pousse les modifications au référentiel canonique, un ensemble de lieutenants / mainteneurs de sous-système à partir desquels il / elle pulls, et un large éventail de développeurs de feuilles qui envoient des correctifs par courrier électronique soit à la liste de diffusion du responsable / projet, soit à l'un des lieutenants / sous-maintenance).
Avec Git, vous avez le choix d'utiliser le protocole SSH ( protocole git enveloppé dans SSH) pour publier les modifications, avec des outils tels que "git shell" (pour aider à la sécurité, limiter l'accès aux comptes shell) ou Gitosis (pour gérer l'accès sans avoir besoin de comptes shell séparés ) et HTTPS avec WebDAV, avec authentification HTTP ordinaire.
Avec CVS, vous avez le choix entre le protocole pserver personnalisé non chiffré (texte brut) ou l'utilisation d' un shell distant (où vous devriez vraiment utiliser SSH ) pour publier vos modifications, ce qui pour un système de contrôle de version centralisé signifie valider vos modifications (créer des commits). Eh bien, vous pouvez également tunneliser le protocole «pserver» en utilisant SSH, et il existe trois outils qui automatisent cela ... mais je ne pense pas que ce soit aussi simple que par exemple Gitosis.
En général, les systèmes de contrôle de version distribués, tels que Git, offrent une sélection beaucoup plus large de flux de travail possibles. Avec les systèmes de contrôle de version centralisés, tels que CVS, vous devez nécessairement faire la distinction entre les personnes ayant un accès de validation au référentiel et celles qui n'en ont pas ... et CVS n'offre aucun outil pour vous aider à accepter les contributions (via des correctifs) de personnes sans valider l'accès.