tag remote practices from example delete create best git version-control configuration repository rcs

remote - git push tag



¿Cuáles son las diferentes versiones de formato de repositorio(para la configuración core.repositoryFormatVersion) en git? (2)

Noté una opción predeterminada en git core.repositoryFormatVersion que por defecto es 0, pero ¿qué son las "versiones en formato de repositorio" y qué diferencia funcional hacen?


Es para compatibilidad futura: si los desarrolladores de git encuentran que es necesario cambiar la forma en que se almacenan los repositorios en el disco para habilitar alguna característica nueva, entonces pueden hacer que los repos actualizados tengan una core.repositoryformatversion de 1 . Luego, las versiones más nuevas de git que conozcan ese nuevo formato activarán el código para tratar con él, y las versiones más antiguas de git que no cometan errores con la "Expected git repo version <= 0, found 1. Please upgrade Git" .

A partir de ahora, la única versión de formato de repositorio definida o reconocida es 0 , lo que denota el formato que ha utilizado cada lanzamiento público de git.


git 2.7 (noviembre de 2015) agrega mucha más información en la nueva Documentation/technical/repository-version.txt .
Consulte commit 067fbd4 , commit 00a09d5 (23 de junio de 2015) por Jeff King ( peff ) .
(Fusionada por Junio ​​C Hamano - gitster - in commit fa46579 , 26 de octubre de 2015)

Ahora puede definir "extensiones" y usar core.repositoryformatversion como un "marcador" para señalar la existencia de dichas extensiones, en lugar de tener que cambiar el número de versión de Git en sí mismo:

Si tuviéramos que cambiar la versión del repositorio por cada cambio de este tipo, entonces cualquier implementación que comprenda la versión X también tendría que entender X-1 , X-2 , etc., incluso si las incompatibilidades pueden estar en partes ortogonales del sistema, y de lo contrario, no hay razón para que no podamos implementar una sin la otra (o, lo que es más importante, que el usuario no puede elegir usar una función sin la otra, lo que hace que la compensación solo sea compatible para esa función en particular).

Este parche documenta la estrategia de repositoryformatversion formato del repositoryformatversion existente e introduce un nuevo formato, "1", que permite a un repositorio especificar que debe ejecutarse con un conjunto arbitrario de extensiones .

Extractos del documento:

Cada repositorio de git está marcado con una versión numérica en la clave core.repositoryformatversion de su archivo de config . Esta versión especifica las reglas para operar en los datos del repositorio en disco.

Tenga en cuenta que esto se aplica solo para acceder directamente al contenido del disco del repositorio.
Un cliente anterior que solo comprende el formato 0 todavía puede conectarse a través de git:// a un repositorio con el formato 1 , siempre que el proceso del servidor entienda el formato 1 .

Versión 0

Este es el formato definido por la versión inicial de git, que incluye, entre otros, el formato del directorio del repositorio, el archivo de configuración del repositorio y el almacenamiento de objetos y referencias.

Versión 1

Este formato es idéntico a la versión 0 , con las siguientes excepciones:

  1. Al leer la variable core.repositoryformatversion , una implementación de git que admita la versión 1 DEBE leer también las claves de configuración que se encuentran en la sección de extensions del archivo de configuración.

  2. Si un repositorio de la versión 1 especifica alguna extensions.* Claves que el git en ejecución no haya implementado, la operación NO DEBE continuar. De manera similar, si la implementación no comprende el valor de cualquier clave conocida, la operación NO DEBE continuar.

Esto puede ser usado, por ejemplo:

  • para informar a git que los objetos no deben podarse basándose únicamente en la accesibilidad de las puntas de referencia (por ejemplo, porque tiene hijos "compartidos - compartidos")

  • que las referencias se almacenan en un formato además de los habituales directorios "refs" y "empaquetado-refs"

Ahora, este es realmente un enfoque original de toda la política de número de versión de lanzamiento y su política semver .

Debido a que saltamos al formato "1", y debido a que el formato "1" requiere que un git en ejecución sepa sobre las extensiones mencionadas, sabemos que las versiones anteriores del código no harán algo peligroso cuando se enfrenten con estos nuevos formatos.

Por ejemplo, si el usuario elige usar el almacenamiento de la base de datos para las referencias, puede configurar la configuración "extensions.refbackend" en "db".
Las versiones anteriores de git no entenderán el formato "1" y la fianza.
Las versiones de git que entienden "1" pero no conocen "refbackend", o que conocen "refbackend" pero no sobre "db", se rehusarán a ejecutar.
Esto es molesto, por supuesto, pero mucho mejor que la alternativa de afirmar que no hay refs en el repositorio, o escribir en una ubicación que otras implementaciones no leerán.

Tenga en cuenta que aquí solo estamos definiendo las reglas para el formato 1.
Nosotros nunca escribimos el formato 1 nosotros mismos; es una herramienta que está destinada a ser utilizada por los usuarios y futuras extensiones para brindar seguridad con las implementaciones anteriores .

Como primera extensión, tendrá con git 2.7 preciousObjects :

Si esta extensión se usa en un repositorio, entonces no se deben ejecutar operaciones que puedan eliminar objetos del almacenamiento de objetos. Esto puede ser útil si está compartiendo ese almacenamiento con otros repositorios cuyas referencias no puede ver.

El doc menciona:

Cuando la clave de configuración extensions.preciousObjects se establece en true , los objetos en el repositorio NO DEBEN ser eliminados (por ejemplo, por git-prune o git repack -d ).

Es decir:

Por ejemplo, si lo hace:

$ git clone -s parent child $ git -C parent config extensions.preciousObjects true $ git -C parent config core.repositoryformatversion 1

ahora tiene seguridad adicional al ejecutar git en el repositorio principal.
Las ciruelas pasas y los paquetes se eliminarán con un error, y git gc omitirá esas operaciones (continuará empaquetando referencias y realizará otras operaciones que no sean objetos).
Las versiones anteriores de git, cuando se ejecutan en el repositorio, fallarán en cada operación.

Tenga en cuenta que no configuramos la extensión preciousObjects de forma predeterminada cuando hacemos " clone -s ", ya que al hacerlo se rompe la compatibilidad hacia atrás. Es una decisión que el usuario debe tomar explícitamente.

Tenga en cuenta que este negocio core.repositoryformatversion es antiguo. Realmente viejo. cometer ab9cb76, noviembre de 2005, Git 0.99.9l .
Se hizo inicialmente para la versión db :

Esto hace que la versión del repositorio init-db consciente.

Comprueba si un archivo de configuración existente dice que el repositorio que se reinicializa es de una versión incorrecta y se cancela antes de hacer más daño.

Git 2.22 (Q2 2019) evitará fugas alrededor de la estructura repository_format .

Consulte commit e8805af (28 de febrero de 2019), y commit 1301997 (22 de enero de 2019) de Martin Ågren (``) .
(Fusionada por Junio ​​C Hamano - gitster - in commit 6b5688b , 20 de marzo de 2019)

setup : corregir las fugas de memoria con struct repository_format

Después de que configuramos una struct repository_format , posee varias piezas de memoria asignada. Entonces, o bien usamos esos miembros, porque decidimos que queremos usar el formato de repositorio "candidato", o descartamos el espacio de candidato / scratch.
En el primer caso, transferimos la propiedad de la memoria a unas pocas variables globales. En este último caso, simplemente descartamos la estructura y terminamos perdiendo memoria.

Introduzca una macro de inicialización REPOSITORY_FORMAT_INIT y una función clear_repository_format() , que se utilizará en cada lado de read_repository_format() . Para tener una propiedad de memoria clara y simple, permita que todos los usuarios de struct repository_format dupliquen las cadenas que toman de ella, en lugar de robar los punteros.

Llame a clear_...() al comienzo de la read_...() lugar de simplemente poner a cero la estructura, ya que a veces ingresamos a la función varias veces.
Por lo tanto, es importante inicializar la estructura antes de llamar a read_...() , así que documéntelo.
También es importante porque es posible que ni siquiera llamemos read_...() antes de que llamemos clear_...() , vea, por ejemplo, builtin/init-db.c .

Teach read_...() para borrar la estructura en el error, para que se restablezca a un estado seguro, y documente esto. (En setup_git_directory_gently() , nos fijamos en repo_fmt.hash_algo incluso si repo_fmt.version es -1, lo que en realidad no se suponía que hiciéramos según la API. Después de esta confirmación, está bien.)