La principal diferencia es que (como ya se dijo en otras respuestas) CVS es el sistema de control de versiones centralizado (antiguo), mientras que Git se distribuye.
Pero incluso si usa el control de versiones para un solo desarrollador, en una sola máquina (cuenta única), existen algunas diferencias entre Git y CVS:
Configuración de repositorio . Git almacena el repositorio en el .git
directorio en el directorio superior de su proyecto; CVS requiere la configuración de CVSROOT, un lugar central para almacenar información de control de versiones para diferentes proyectos (módulos). La consecuencia de ese diseño para el usuario es que importar fuentes existentes en el control de versiones es tan simple como "git init && git add. && git commit" en Git, mientras que es más complicado en CVS.
Operaciones atómicas . Como CVS al principio era un conjunto de scripts en torno al sistema de control de versiones RCS por archivo, los commits (y otras operaciones) no son atómicos en CVS; Si una operación en el repositorio se interrumpe en el medio, el repositorio se puede dejar en un estado inconsistente. En Git todas las operaciones son atómicas: o tienen éxito como un todo, o fallan sin ningún cambio.
Conjuntos de cambios . Los cambios en CVS son por archivo, mientras que los cambios (commits) en Git siempre se refieren a todo el proyecto. Este es un cambio de paradigma muy importante . Una de las consecuencias de esto es que es muy fácil en Git revertir (crear un cambio que deshaga) o deshacer todo el cambio; Otra consecuencia es que en CVS es fácil realizar pagos parciales, mientras que actualmente es casi imposible en Git. El hecho de que los cambios sean por archivo, agrupados, condujo a la invención del formato GNU Changelog para enviar mensajes en CVS; Los usuarios de Git usan (y algunas herramientas de Git esperan) diferentes convenciones, con una sola línea que describe (resume) el cambio, seguido de una línea vacía, seguida de una descripción más detallada de los cambios.
Nombrar revisiones / números de versión . Hay otro problema relacionado con el hecho de que en CVS los cambios son por archivos: los números de versión (como puede ver a veces en la expansión de palabras clave , ver más abajo) como 1.4 refleja la cantidad de tiempo que se ha cambiado el archivo dado. En Git, cada versión de un proyecto en su conjunto (cada confirmación) tiene su nombre único dado por la identificación SHA-1; por lo general, los primeros 7-8 caracteres son suficientes para identificar una confirmación (no puede usar un esquema de numeración simple para las versiones en el sistema de control de versiones distribuido, que requiere autoridad central de numeración). En CVS para tener el número de versión o el nombre simbólico que se refiere al estado del proyecto en su conjunto, usa etiquetas; lo mismo es cierto en Git si desea usar un nombre como 'v1.5.6-rc2' para alguna versión de un proyecto ... pero las etiquetas en Git son mucho más fáciles de usar.
Fácil ramificación . Las sucursales en CVS son, en mi opinión, demasiado complicadas y difíciles de tratar. Debe etiquetar las ramas para tener un nombre para toda una rama del repositorio (e incluso eso puede fallar en algunos casos, si no recuerdo mal, debido al manejo por archivo). Agregue a eso el hecho de que CVS no tiene seguimiento de fusión , por lo que debe recordar o etiquetar manualmente las fusiones y los puntos de ramificación, y proporcionar manualmente la información correcta para "cvs update -j" para fusionar ramas, y esto hace que se ramifique ser innecesariamente difícil de usar. En Git, crear y fusionar ramas es muy fácil; Git recuerda toda la información requerida por sí misma (por lo que fusionar una rama es tan fácil como "git merge branchname ") ... tenía que hacerlo, porque el desarrollo distribuido naturalmente conduce a múltiples ramas.
Esto significa que puede usar ramas temáticas , es decir, desarrollar una característica separada en varios pasos en una rama de característica separada.
Renombrar (y copiar) el seguimiento . Los cambios de nombre de archivos no son compatibles con CVS, y el cambio de nombre manual puede dividir el historial en dos o generar un historial no válido donde no se puede recuperar correctamente el estado de un proyecto antes de cambiar el nombre. Git utiliza la detección heurística de cambio de nombre, basada en la similitud de contenido y nombre de archivo (esta solución funciona bien en la práctica). También puede solicitar la detección de copia de archivos. Esto significa que:
- al examinar la confirmación especificada, obtendría información de que se cambió el nombre de algún archivo,
- la combinación correcta tiene en cuenta los cambios de nombre (por ejemplo, si el archivo se cambió de nombre solo en una rama)
- "git blame", el (mejor) equivalente de "cvs annotate", una herramienta para mostrar el historial en línea del contenido de un archivo, puede seguir el movimiento del código también a través de los cambios de nombre
Archivos binarios . CVS solo tiene un soporte muy limitado para archivos binarios (p. Ej., Imágenes), y requiere que los usuarios marquen los archivos binarios explícitamente al agregarlos (o más tarde usando "cvs admin", o mediante envoltorios para hacerlo automáticamente en función del nombre del archivo), para evitar la manipulación de archivo binario mediante conversión de fin de línea y expansión de palabras clave. Git detecta automáticamente archivos binarios basados en contenidos de la misma manera que CNU diff y otras herramientas lo hacen; Puede anular esta detección utilizando el mecanismo gitattributes. Además, los archivos binarios están a salvo de la destrucción irrecuperable gracias al valor predeterminado en 'safecrlf' (y al hecho de que debe solicitar la conversión de final de línea, aunque esto puede activarse de forma predeterminada según la distribución) y esa palabra clave (limitada) la expansión es un estricto 'opt-in' en Git.
Expansión de palabras clave . Git ofrece un conjunto muy, muy limitado de palabras clave en comparación con CVS (por defecto). Esto se debe a dos hechos: los cambios en Git son por repositorio y no por archivo, y Git evita modificar archivos que no cambiaron al cambiar a otra rama o rebobinar a otro punto en la historia. Si desea incrustar el número de revisión usando Git, debe hacerlo usando su sistema de compilación, por ejemplo, siguiendo el ejemplo del script GIT-VERSION-GEN en las fuentes del kernel de Linux y en las fuentes de Git.
La modificación se compromete . Debido a que en VCS distribuidos, como Git, el acto de publicación es independiente de la creación de una confirmación, se puede cambiar (editar, reescribir) parte no publicada del historial sin incomodar a otros usuarios. En particular, si observa un error tipográfico (u otro error) en el mensaje de confirmación, o un error en la confirmación, simplemente puede usar "git commit --amend". Esto no es posible (al menos no sin piratería informática) en CVS.
Más herramientas . Git ofrece muchas más herramientas que CVS. Uno de los más importantes es " git bisect " que se puede utilizar para encontrar un commit (revisión) que introdujo un error; Si sus confirmaciones son pequeñas y autónomas, debería ser bastante fácil descubrir dónde está el error.
Si colabora con al menos otro desarrollador, también encontrará las siguientes diferencias entre Git y CVS:
Comprometerse antes de fusionar Git usa commit-before-merge en lugar de, como CVS, merge-before-commit (o update-then-commit ). Si mientras estaba editando archivos, preparándose para crear una nueva confirmación (nueva revisión), otra persona creó una nueva confirmación en la misma rama y ahora está en el repositorio, CVS lo obliga a actualizar primero su directorio de trabajo y resolver conflictos antes de permitirle comprometerse. Este no es el caso con Git. Primero se compromete, guarda su estado en el control de versiones, luego combina otros cambios de desarrollador. También puede solicitar al otro desarrollador que fusione y resuelva conflictos.
Si prefiere tener un historial lineal y evitar fusiones, siempre puede usar el flujo de trabajo commit-merge-recommit a través de "git rebase" (y "git pull --rebase"), que es similar a CVS en que repite sus cambios en la parte superior de estado actualizado. Pero siempre te comprometes primero.
No es necesario un repositorio central Con Git no hay necesidad de tener un solo lugar central donde confirme sus cambios. Cada desarrollador puede tener su propio repositorio (o mejores repositorios: uno privado en el que él / ella realiza el desarrollo, y uno público en el que publica esa parte que está lista), y pueden extraer / recuperar los repositorios de cada uno, en moda simétrica Por otro lado, es común que un proyecto más grande tenga un repositorio central socialmente definido / nominado del que todos obtienen (obtienen cambios).
Finalmente, Git ofrece muchas más posibilidades cuando se necesita la colaboración con un gran número de desarrolladores. A continuación hay diferencias entre CVS en Git para diferentes etapas de interés y posición en un proyecto (bajo control de versión usando CVS o Git):
lurker . Si solo le interesa obtener los últimos cambios de un proyecto ( sin propagación de sus cambios ) o realizar un desarrollo privado (sin contribuir a los proyectos originales); o utiliza proyectos extranjeros como base de su propio proyecto (los cambios son locales y no tiene sentido publicarlos).
Git admite aquí el acceso anónimo no autenticado de solo lectura a través de un git://
protocolo eficiente personalizado , o si está detrás del bloqueo del firewall DEFAULT_GIT_PORT
(9418) puede usar HTTP simple.
Para CVS, la solución más común (según tengo entendido) para el acceso de solo lectura es la cuenta de invitado para el protocolo 'pserver' en CVS_AUTH_PORT
(2401), generalmente llamado "anónimo" y con contraseña vacía. Las credenciales se almacenan de manera predeterminada en el $HOME/.cvspass
archivo, por lo que debe proporcionarlas solo una vez; aún así, esto es un poco de barrera (debe saber el nombre de la cuenta de invitado o prestar atención a los mensajes del servidor CVS) y molestia.
desarrollador marginal (contribuyente de hojas) . Una forma de propagar sus cambios en OSS es enviando parches por correo electrónico . Esta es la solución más común si usted es (más o menos) desarrollador accidental, envía un solo cambio o una sola corrección de error. Por cierto. el envío de parches puede realizarse a través de un panel de revisión (sistema de revisión de parches) o un medio similar, no solo por correo electrónico.
Git ofrece aquí herramientas que ayudan en este mecanismo de propagación (publicación) tanto para el remitente (cliente) como para el mantenedor (servidor). Para las personas que desean enviar sus cambios por correo electrónico, existe la herramienta " git rebase " (o "git pull --rebase") para reproducir sus propios cambios sobre la versión actual actual, por lo que sus cambios están sobre la versión actual (son nuevos ) y " parche de formato git " para crear correo electrónico con mensaje de confirmación (y autoría), cambiar en forma de formato de diferencias unificado (extendido) (más diffstat para una revisión más fácil). El mantenedor puede convertir dicho correo electrónico directamente en commit preservando toda la información (incluido el mensaje de commit) usando " git am ".
CVS no ofrece tales herramientas: puede usar "cvs diff" / "cvs rdiff" para generar cambios, y usar el parche GNU para aplicar los cambios, pero que yo sepa, no hay forma de automatizar la aplicación del mensaje de confirmación. CVS estaba destinado a ser utilizado en el cliente <-> servidor de moda ...
teniente . Si es el responsable del mantenimiento de una parte separada de un proyecto (subsistema), o si el desarrollo de su proyecto sigue el flujo de trabajo de "red de confianza" utilizado en el desarrollo del kernel de Linux ... o simplemente si tiene su propio repositorio público y los cambios desea publicar son demasiado grandes para enviar por correo electrónico como serie de parches , puede enviar una solicitud de extracción al mantenedor (principal) del proyecto.
Esta es una solución específica para distribuido los sistemas de control de versiones , por lo que, por supuesto, CVS no admite esa forma de colaboración. Incluso hay una herramienta llamada "git request-pull" que ayuda a preparar el correo electrónico para enviar al mantenedor con la solicitud de extracción desde su repositorio. Gracias a "git bundle" puede usar este mecanismo incluso sin tener un repositorio público, enviando un paquete de cambios por correo electrónico o sneakernet. Algunos de los sitios de alojamiento de Git como GitHub tienen soporte para notificar que alguien está trabajando (publicado algún trabajo) en su proyecto (siempre que él / ella use el mismo sitio de alojamiento de Git), y para enviar un PM a una especie de solicitud de extracción.
desarrollador principal , es decir, alguien que publica directamente sus cambios (al repositorio principal / canónico). Esta categoría es más amplia para los sistemas de control de versiones distribuidas, ya que tener múltiples desarrolladores con acceso de escritura al repositorio central no es solo un flujo de trabajo posible (puede tener un solo mantenedor que empuje los cambios al repositorio canónico, un conjunto de tenientes / mantenedores de subsistemas desde el cual él / ella pulls, y una amplia gama de desarrolladores de hojas que envían parches por correo a la lista de correo del mantenedor / proyecto o a uno de los lugartenientes / submaintainers).
Con Git tiene la opción de usar el protocolo SSH ( protocolo git envuelto en SSH) para publicar cambios, con herramientas como "git shell" (para ayudar a la seguridad, limitar el acceso de las cuentas de shell) o Gitosis (para administrar el acceso sin requerir cuentas de shell separadas ) y HTTPS con WebDAV, con autenticación HTTP normal.
Con CVS hay una opción entre el protocolo pserver personalizado sin cifrar (texto sin formato) o el uso de shell remoto (donde realmente debería usar SSH ) para publicar sus cambios, lo que para el sistema de control de versiones centralizado significa confirmar sus cambios (crear confirmaciones). Bueno, también puede hacer un túnel del protocolo 'pserver' usando SSH, y hay herramientas de terceros que automatizan esto ... pero no creo que sea tan fácil como, por ejemplo, la gitosis.
En general, los sistemas de control de versiones distribuidos, como Git, proporcionan una selección mucho más amplia de posibles flujos de trabajo. Con los sistemas de control de versiones centralizados, como CVS, necesariamente debe distinguir entre las personas con acceso de confirmación al repositorio y aquellas sin ... y CVS no ofrece ninguna herramienta para ayudar a aceptar contribuciones (a través de parches) de personas sin comprometer el acceso.