La mejor forma de versionar las diferentes twigs de git

Tenemos el siguiente escenario: Tenemos varias versiones base de nuestro juego OpenLieroX; en este momento 0.57, 0.58 y 0.59. Para cada versión base, tenemos una twig separada. Cada versión base tiene varias versiones (como 0.57 beta1-beta8 y rc1, 0.58 beta1-beta9).

Cuando estamos trabajando en cosas nuevas, estamos trabajando en la twig de versión base más alta (ahora que es 0.59). Cuando estamos solucionando algunos errores reportados, lo hacemos en la primera versión (mayormente 0.58) donde eso ocurrió. De vez en cuando, siempre fusionamos todos los cambios en 0.58 a 0.59 (siempre y cuando aún mantengamos y realicemos cambios en la twig anterior).

Todo esto funciona realmente bien hasta que se trata de algunos cambios que queremos tener solo en 0.58 pero no en 0.59. Esto sucedió solo para un caso hasta ahora: el número de versión. Tenemos algún file Version.cpp (y también algunos otros files) que contiene el número de versión. Entonces, cuando queremos lanzar una nueva versión para 0.58, cambiamos la cadena de versiones allí a "0.58 beta10" (o lo que sea). Ahora, cuando hagamos la fusión habitual de 0.58 a 0.59, este cambio también se aplicará. Arreglamos estos casos en este momento sobrescribiéndolo nuevamente con el número de versión correcto (o en casos de otras malas confirmaciones, probablemente una reversión).

Este detalle sobre tales cambios no deseados parece ser un poco feo para mí. ¿Es la forma en que manejamos esto en general mala / poco común? ¿Cómo sería la forma más fácil de hacer esto para get el mismo resultado? Escoger todas las confirmaciones de 0,58 en 0,59 sería mucho más trabajo.


También hay un detalle más que probablemente lo hace más complicado: Mientras trabajo en el código, tengo que establecer ya el número de versión próximo. Esto se debe a que tenemos un motor de networking y es posible que hayamos introducido alguna funcionalidad nueva y que haya códigos en el código como 'if (client-> version ()> = Version (X, Y, Z)) …'. Ahora, cuando presentamos algo nuevo, generalmente significa en algunos puntos tales controles. (Pero estamos tratando de evitar estos cambios en las twigs más antiguas).

Otro problema es que no solo contamos la versión (como 0.58.1, 0.58.2, …) sino que contamos así: 0.58 beta1, 0.58 beta2, …, 0.58 betaX, 0.58 rc1,. .., 0.58, 0.58.1, 0.58.2, … Esto es porque queremos marcarlo como experimental para el comienzo (etapa beta) y luego como mayormente estable o estable. En algunos casos raros, puede haber cambios serios (tal vez el protocolo de networking) incluso entre dos versiones beta diferentes (por supuesto, tratamos de evitarlas, pero a veces no es posible sin).

Con twigs adicionales

Después de 0.59 difiere de 0.58, puede usar una twig de "liberación" separada para los cambios de número de versión en 0.58. Cada versión (excepto la más reciente) tendría su propia twig de "publicación" que solo contiene fusiones desde la twig base y cambios que actualizan el número de versión externa. La estructura de la sucursal podría verse más o less así:

A--------o--B 0.58-release / / ...--o--o--o--o--o--o--o--o 0.58 \ \ \ \ \ \ \ \ C 0.59-release \ \ \ \ / o--o--o--o--o--o--o--o--o--o--o--o 0.59 \ \ o--o--o 0.60 
  • A label el software "0.58 beta9"
  • B label el software "0.58 rc1"
  • 0.58 tiene cambios que aún no se han publicado
  • C label el software "0.59 beta1"
  • 0.59 tiene cambios que aún no se han publicado
  • 0.60 aún no está completamente actualizado con 0.59

O bien, si es muy estricto al hacer solo cambios en A, B, C, etc. que cambian el número de versión externa (no hay cambios significativos en el código, esos pertenecen a las twigs 'base': 0.58, 0.59, etc.), entonces podrías prescindir de las twigs de "lanzamiento". En su lugar, podría usar una HEAD o twig temporal separada (eliminada después de que se haya versionado la versión) para confirmar la actualización de la versión externa y savela en una label.

  AB / / ...--o--o--o--o--o--o--o--o 0.58 \ \ \ \ \ \ \ \ C \ \ \ \ / o--o--o--o--o--o--o--o--o--o--o--o 0.59 \ \ o--o--o 0.60 
  • A label el software "0.58 beta9" y es la label 0.58-beta9
  • B label el software "0.58 rc1" y es la label 0.58-rc1
  • C label el software "0.59 beta1" y es la label 0.59-beta1

Como Git lo hace

También puedes mirar en la forma en que Git hace su propio control de versiones.

Para comstackciones hechas desde un tree de trabajo de Git, el número de versión se genera a partir de la salida de git describe HEAD . El Makefile sabe qué files deben recomstackrse / rebuildse si el número de versión cambia y siempre ejecuta el script GIT-VERSION-GEN para asegurarse de que tiene el número de versión más reciente. El número de versión está disponible en el file Makefile mediante la inclusión del file de versión generado. Se pasa a los files C por un argumento al comstackdor ( -DGIT_VERSION=… ) y se sustituye en los scripts mediante el uso de sed .

Hay algunas disposiciones para anular el número de versión "grabado" en una compilation, pero generalmente solo están ahí para comstackciones realizadas fuera de un tree de trabajo (por ejemplo, una compilation hecha a partir de un tree extraído de un file tar).

Mezcla de cambios de cadenas de versiones con otros cambios

En su adición a su pregunta, declara que debe ajustar el número de versión mientras realiza el desarrollo. Primero, creo que el esquema de la twig "0.58-release" que seh y yo hemos descrito aún puede funcionar para usted. Solo requerirá más disciplina para separar sus cambios. Si piensa en las * twigs de publicación como "lanzadas para testings internas" y no solo "lanzadas a clientes (o para testings externas)", entonces todavía tiene sentido. Realice siempre su desarrollo en la twig base (por ejemplo, "0.58") y fusione siempre la twig base en la twig de publicación (por ejemplo, "0.58-release") antes de hacer una compilation que requiera un número de versión específico (siempre compilation desde tal twig de lanzamiento fusionada).

Si insistes en poner cambios de número de versión y cambios de código (sin fusión) en la misma línea de la historia, entonces me parece que no tendrás más remedio que lidiar con el conflicto cuando se fusionen (a less que vayas con git cherry-pick (por Damien Wilson, o un script de edición automatizado dirigido a git rebase -i ).

Si sus "files de versión" solo contienen información de versiones, puede facilitar la resolución de conflictos utilizando .gitattributes para marcar su file Version.cpp como no modificable.

.gitattributes en el directory que contiene Version.cpp

 /Version.cpp -merge 

Marcarlo así (igual que merge=binary ) siempre causará un conflicto si el file es diferente entre las twigs fusionadas. La versión del tree de trabajo posterior a la fusión adoptará la versión pnetworkingeterminada de la twig que ha retirado (no la de la (s) twig (s) que se está (n) fusionando), de modo que puede simplemente git add Version.cpp && git commit para finalizar el fusionar (suponiendo que todos los demás conflictos también se resuelven).

Parece que lo que estás haciendo es la manera correcta (para este resultado). Pero tal vez deberías reconsiderar tu sistema de versión.

Puede agregar una versión de compilation, 0.58.1, 0.58.2, etc. de esa manera puede agregar tantas cosas como desee, y aún así lo llamará colectivamente "0.58", aunque tenga un número de compilation .

Una vez publicado, puede agregar beta, RC, lo que sea, pero eso no es algo que el sistema de versiones deba preocuparse.

La versión "0.58.3 (beta1)" solo se refiere a la versión 0.58.3. La parte beta1 es información humana y no una preocupación del sistema de control de versiones.

Si entiendo el problema, parece que quieres include un cierto subset de confirmaciones de diferentes twigs. Si ese es el caso, puede que solo necesites ejecutar git cherry-pick y solo aplicar los commit que desees.

Más información sobre el command en git docs y en Git Ready .

La parte difícil es aislar la designación de la versión del código subyacente.

Puede flotar una twig de designación de versión encima de la twig de código liberada, de manera que pueda fusionar de forma segura todo ese código desde su twig liberada (0.58) a su twig principal (0.59) en cualquier punto, sin mezclar las designaciones de versiones conflictivas . Esa twig que designa la versión nunca se fusionaría de nuevo a la twig liberada; simplemente lo volverá a establecer en la parte superior de la twig liberada cuando desee include un código nuevo en una versión versionada.

Puede organizar esto fácilmente con la siguiente input en su file .git / config :

 [branch "0.58-release"] remote = . merge = refs/heads/0.58 rebase = true 

Con eso, su twig de lanzamiento se llama "0.58", y usted haría sus comstackciones versionadas usando la twig "0.58-release". Cuando llegue el momento de crear una compilation de lanzamiento, emitiría los siguientes commands:

 git checkout 0.58-release git pull # Edit the version-designating file. git commit -a -m'Updated version.' 

Todos los cambios en los files de designación de versión solo se encuentran en la twig "58 versiones" y se pueden mover de forma segura con git rebase . Alternativamente, si desea que cada cambio en el file de designación de versión se adhiera al estado del código de la twig "0.58", puede fusionar la twig "0.58" en la twig "0.58-release" en lugar de rebasar "0.58- lanzamiento "encima de" 0.58 ".