Esto es lo que no me gusta de git:
En primer lugar, creo que la idea distribuida se opone a la realidad. Todos los que realmente usan git lo hacen de manera centralizada, incluso Linus Torvalds. Si el kernel se administrara de forma distribuida, eso significaría que en realidad no podría descargar las fuentes "oficiales" del kernel, no habría ninguna, tendría que decidir si quiero la versión de Linus o la de Joe, o la versión de Bill. Obviamente, eso sería ridículo, y es por eso que hay una definición oficial que Linus controla mediante un flujo de trabajo centralizado.
Si acepta que desea una definición centralizada de sus cosas, entonces queda claro que los roles del servidor y del cliente son completamente diferentes, por lo que el dogma de que el software del cliente y del servidor debe ser el mismo se vuelve puramente limitante. El dogma de que los datos del cliente y del servidor deben ser los mismos se vuelve evidentemente ridículo, especialmente en una base de código que tiene quince años de historia que a nadie le importa pero que todos tendrían que clonar.
Lo que realmente queremos hacer con todas esas cosas viejas es tirarlas en un armario y olvidar que está allí, como lo hace cualquier VCS normal. El hecho de que git lo transporte todo de un lado a otro a través de la red todos los días es muy peligroso, porque te fastidia que lo podes. Esa poda implica muchas decisiones tediosas y puede salir mal. Entonces, la gente probablemente mantendrá una serie completa de repositorios de instantáneas de varios puntos en la historia, pero ¿no era para eso el control de fuente en primer lugar? Este problema no existió hasta que alguien inventó el modelo distribuido.
Git anima activamente a las personas a reescribir la historia, y lo anterior probablemente sea una de las razones para ello. Cada VCS normal hace que la reescritura del historial sea imposible para todos, excepto para los administradores, y se asegura de que los administradores no tengan ninguna razón para considerarlo. Corrígeme si me equivoco, pero hasta donde yo sé, git no proporciona ninguna forma de otorgar acceso de escritura a los usuarios normales, pero no les permite reescribir el historial. Eso significa que cualquier desarrollador con rencor (o que todavía esté luchando con la curva de aprendizaje) podría destruir todo el código base. ¿Cómo apretamos ese? Bueno, o haces copias de seguridad periódicas de todo el historial, es decir, mantienes el historial al cuadrado, o prohíbes el acceso de escritura a todos excepto a un pobre idiota que recibiría todas las diferencias por correo electrónico y las combinaría a mano.
Tomemos un ejemplo de un gran proyecto bien financiado y veamos cómo funciona git para ellos: Android. Una vez decidí jugar con el sistema Android. Descubrí que se suponía que debía usar un montón de scripts llamados repo para acceder a su git. Algunos repositorios se ejecutan en el cliente y otros en el servidor, pero ambos, por su propia existencia, ilustran el hecho de que git está incompleto en cualquiera de las dos capacidades. Lo que sucedió es que no pude sacar las fuentes durante aproximadamente una semana y luego me rendí por completo. Habría tenido que extraer una gran cantidad de datos de varios repositorios diferentes, pero el servidor estaba completamente sobrecargado con gente como yo. Repo estaba agotando el tiempo y no pudo reanudar desde donde se había agotado. Si git es tan distribuible, habrías pensado que ' Habría hecho algún tipo de cosa peer-to-peer para aliviar la carga en ese servidor. Git es distribuible, pero no es un servidor. Git + repo es un servidor, pero el repositorio no es distribuible porque es solo una colección ad-hoc de hacks.
Una ilustración similar de la insuficiencia de git es gitolite (y su antepasado que aparentemente no funcionó tan bien). Gitolite describe su trabajo como facilitar la implementación de un servidor git. Nuevamente, la mera existencia de esto prueba que git no es un servidor, como tampoco es un cliente. Es más, nunca lo será, porque si se convirtiera en cualquiera de los dos, estaría traicionando sus principios fundacionales.
Incluso si creyeras en lo distribuido, git seguiría siendo un desastre. ¿Qué es, por ejemplo, una rama? Dicen que implícitamente crea una rama cada vez que clona un repositorio, pero eso no puede ser lo mismo que una rama en un solo repositorio. Así que son al menos dos cosas diferentes a las que se hace referencia como ramas. Pero luego, también puede rebobinar en un repositorio y simplemente comenzar a editar. ¿Es como el segundo tipo de rama o es algo diferente de nuevo? Tal vez depende del tipo de repositorio que tengas, oh sí, aparentemente el repositorio tampoco es un concepto muy claro. Los hay normales y desnudos. No puede presionar a uno normal porque la parte desnuda puede desincronizarse con su árbol de origen. Pero no se puede importar a uno solo porque ellos no pensaron en eso. Entonces tienes que importar a uno normal, clone eso a uno simple que los desarrolladores hayan alcanzado, y cvexportarlo a una copia de trabajo de cvs que aún debe registrarse en cvs. ¿Quién puede molestarse? ¿De dónde vinieron todas estas complicaciones? De la propia idea distribuida. Al final me deshice de la gitolita porque me imponía aún más de estas restricciones.
Git dice que la ramificación debería ser liviana, pero muchas empresas ya tienen un problema grave de sucursales deshonestas, por lo que habría pensado que la ramificación debería ser una decisión trascendental con una vigilancia estricta. Aquí es donde la fuerza realmente brilla ...
Forzosamente, rara vez necesita sucursales porque puede hacer malabares con los conjuntos de cambios de una manera muy ágil. Por ejemplo, el flujo de trabajo habitual es sincronizar con la última versión buena conocida en la línea principal y luego escribir su función. Siempre que intente modificar un archivo, la diferencia de ese archivo se agregará a su "conjunto de cambios predeterminado". Cuando intenta registrar el conjunto de cambios, automáticamente intenta fusionar las noticias de la línea principal en su conjunto de cambios (de manera efectiva, reorganizándolo) y luego confirma. Este flujo de trabajo se aplica sin necesidad de que lo comprenda. Mainline recopila así un historial de cambios que puede elegir fácilmente más adelante. Por ejemplo, suponga que desea revertir uno anterior, digamos, el anterior al anterior al último. Sincroniza con el momento anterior al cambio ofensivo, marca los archivos afectados como parte del conjunto de cambios, sincronizar con el momento posterior y fusionar con "siempre mío". (Había algo muy interesante allí: sincronizar no significa tener lo mismo; si un archivo es editable (es decir, en un conjunto de cambios activo), la sincronización no lo golpeará, pero se marcará como pendiente de resolución). una lista de cambios que deshace la infractora. Combine las noticias siguientes y tendrá una lista de cambios que puede colocar en la parte superior de la línea principal para obtener el efecto deseado. En ningún momento reescribimos ninguna historia. Combine las noticias siguientes y tendrá una lista de cambios que puede colocar en la parte superior de la línea principal para obtener el efecto deseado. En ningún momento reescribimos ninguna historia. Combine las noticias siguientes y tendrá una lista de cambios que puede colocar en la parte superior de la línea principal para obtener el efecto deseado. En ningún momento reescribimos ninguna historia.
Ahora, suponiendo que a la mitad de este proceso, alguien corre hacia ti y te dice que dejes todo y arregles algún error. Simplemente dé un nombre a su lista de cambios predeterminada (un número en realidad), luego "suspenda", corrija el error en la lista de cambios predeterminada ahora vacía, consúltelo y reanude la lista de cambios nombrada. Es típico tener varias listas de cambios suspendidas al mismo tiempo en el que prueba cosas diferentes. Es fácil y privado. Obtienes lo que realmente quieres de un régimen secundario sin la tentación de posponer las cosas o acobardarte en la fusión con la línea principal.
Supongo que sería teóricamente posible hacer algo similar en git, pero git hace prácticamente cualquier cosa en lugar de afirmar un flujo de trabajo que aprobamos. El modelo centralizado es un montón de simplificaciones válidas en relación con el modelo distribuido, que es una generalización inválida. Está tan sobregeneralizado que básicamente espera que implementes el control de código fuente, como lo hace el repositorio.
La otra cosa es la replicación. En git, todo es posible, así que tienes que averiguarlo por ti mismo. Forzosamente, obtienes un caché sin estado de manera efectiva. La única configuración que necesita saber es dónde está el maestro, y los clientes pueden apuntar al maestro o al caché a su discreción. Es un trabajo de cinco minutos y no puede salir mal.
También tiene activadores y formularios personalizables para afirmar revisiones de código, referencias de bugzilla, etc. y, por supuesto, tiene ramas para cuando realmente las necesite. No es un caso claro, pero está cerca y es muy fácil de configurar y mantener.
Considerándolo todo, creo que si sabe que va a trabajar de forma centralizada, lo que hace todo el mundo, también puede utilizar una herramienta que fue diseñada con eso en mente. Git está sobrevalorado debido al ingenio temible de Linus junto con la tendencia de las personas a seguirse como ovejas, pero su principal razón de ser no resiste el sentido común, y al seguirlo, git se ata las manos con los dos grandes dogmas de que (a) el software y (b) los datos tienen que ser los mismos tanto en el cliente como en el servidor, y eso siempre lo hará complicado y poco convincente en el trabajo centralizado.