2008-09-23 10 views
29

En este momento, estamos usando Perforce para el control de versiones. Tiene la característica útil de un número de cambio estrictamente creciente que podemos usar para referirnos a construcciones, por ejemplo, "obtendrás la corrección de errores si tu construcción es al menos 44902".Crear secuenciación al usar el control de versión distribuida

Me gustaría cambiar a utilizar un sistema distribuido (probablemente git) para facilitar la bifurcación y el trabajo desde casa. (Ambos son perfectamente posibles con Perforce, pero el flujo de trabajo de git tiene algunas ventajas.) Así que, aunque el "desarrollo tributario" se distribuiría y no se referiría a una secuencia de revisión común, mantendríamos un repo master git que todos los cambios serían Necesito alimentarme antes de que se cree una construcción.

¿Cuál es la mejor manera de preservar el estricto aumento de los ID de construcción? La forma más sencilla en que puedo pensar es tener algún tipo de enlace post-commit que se activa siempre que el repositorio maestro se actualice, y registra (el hash de) el nuevo objeto de árbol (¿o el objeto de confirmación?) Soy nuevo en git) con una base de datos centralizada que entrega identificadores. (Digo "base de datos", pero probablemente lo haría con etiquetas git, y simplemente busco el siguiente número de etiqueta disponible o algo así. Así que la "base de datos" sería realmente .git/refs/tags/build-id /.)

Esto es viable, pero me pregunto si existe una manera más fácil, ya implementada, o estándar/de "mejores prácticas" para lograr esto.

Respuesta

28

Secundo la sugerencia de utilizar git describe. Siempre que tenga una política de control de versiones en su sano juicio y no haga nada loco con su repositorio, git describe siempre será monótono (al menos tan monótona como sea posible, cuando su historial de revisiones sea un DAG en lugar de un árbol) y único.

Una pequeña demostración:

git init 
git commit --allow-empty -m'Commit One.' 
git tag -a -m'Tag One.' 1.2.3 
git describe # => 1.2.3 
git commit --allow-empty -m'Commit Two.' 
git describe # => 1.2.3-1-gaac161d 
git commit --allow-empty -m'Commit Three.' 
git describe # => 1.2.3-2-g462715d 
git tag -a -m'Tag Two.' 2.0.0 
git describe # => 2.0.0 

La salida de git describe consta de los siguientes componentes:

  1. El último etiqueta accesible desde la que se comprometan está pidiendo que describen
  2. El número de confirmaciones entre la confirmación y la etiqueta (si no es cero)
  3. La id (abreviada) de la confirmación (si la # 2 no es cero)

# 2 es lo que hace que la salida sea monótona, la # 3 es lo que la hace única. # 2 y # 3 se omiten, cuando la confirmación es la etiqueta, lo que hace que git describe también sea adecuado para lanzamientos de producción.

+1

Las etiquetas no manejan las ramas y la fusión. La forma automática correcta de agregar la secuencia adecuada es contando un número de confirmaciones detrás de la confirmación actual. Esto se explica en mi respuesta a continuación. – squadette

1

Usaría "Etiquetas" Crea una etiqueta siempre que tenga una compilación exitosa (o incluso fallida), y podrá identificar esa compilación para siempre. No es exactamente lo mismo, pero proporciona esos números de compilación, al tiempo que proporciona los beneficios del desarrollo distribuido.

4

git tag puede ser suficiente para lo que necesita. Escoja un formato de etiqueta que, de otro modo, todos aceptarán no usar.

Nota: cuando etiqueta localmente, un git push no actualizará las etiquetas en el servidor. Use git push --tags para eso.

2

Debe investigar git describe. Proporciona una cadena única que describe la rama actual (o cualquier ID de confirmación pasada) en términos de la última etiqueta anotada, el número de confirmaciones desde esa etiqueta y una identificación de confirmación abreviada del jefe de la sucursal.

Es de suponer que tiene una única rama que realiza liberaciones controladas de compilación desactivadas. En este caso, etiquetaría una confirmación temprana con un formato de etiqueta conocido y luego usaría git describe con la opción --match para describir el HEAD actual relativo a una etiqueta conocida. A continuación, puede utilizar el resultado de git describe tal cual o si realmente desea un solo número, puede usar una expresión regular para cortar el número de la etiqueta.

Suponiendo que nunca retrocede la rama, el número de confirmaciones siguientes siempre identificará un punto único en el historial de la sucursal.

p. Ej. (Usando bash o similares)

# make an annotated tag to an early build in the repository: 
git tag -a build-origin "$some_old_commitid" 

# describe the current HEAD against this tag and pull out a build number 
expr "$(git describe --match build-origin)" : 'build-origin-\([0-9]*\)-g' 
0

Como usted probablemente sabe, git calcula un hash (un número) que identifica de forma exclusiva un nodo de la historia. Usando estos, aunque no están aumentando estrictamente, parece que sería lo suficientemente bueno. (Mejor aún, siempre corresponden a la fuente, por lo que si tiene el hash, tiene el mismo código.) Son números grandes, pero en su mayoría puede salir adelante con 6 dígitos más o menos.

Por ejemplo,

Ese error se fija en 064f2ea ...

+6

Ok, pero tengo 1a92b6. ¿Tengo la corrección de errores? – sfink

+0

git rev-list 1a92b6 | grep 064f2ea -> si esto da algo, lo tienes; de lo contrario no lo haces. – EfForEffort

+0

git branch --contains = le dará todas las ramas que contienen el (a menudo más útil) –

0

Con Mercurial puede utilizar el siguiente comando:

# get the parents id, the local revision number and the tags 
[[email protected]:~/my-repo]$ hg id -nibt 
03b6399bc32b+ 23716+ default tip 

Ver hg identify

+0

Eso no es estrictamente creciente. – OrangeDog

30

monótonamente creciente número correspondiente a la corriente commit se podría generar con

git log --pretty=oneline | wc -l 

que devuelve un solo número . También puede agregar el sha1 actual a ese número, para agregar unicidad.

Este enfoque es mejor que git describe, porque no requiere que agregue ninguna etiqueta, y maneja automáticamente las fusiones.

Podría tener problemas con el rebasado, pero la rebase es una operación "peligrosa" de todos modos.

+0

El problema con este enfoque es que no podrá distinguir ramas. Puede agregar el nombre de la rama para construir la identificación también. – timurb

+0

Crea ciertos binarios (como -beta, -estable, -nightly) desde ciertas ramas. Por lo tanto, el nombre de la sucursal es "externo" al número de compilación. – squadette

8
git rev-list BRANCHNAME --count 

esto es mucho menos recursos que

git log --pretty=oneline | wc -l 
Cuestiones relacionadas