¿Buenas formas de administrar un registro de cambios usando git?

214

He estado usando Git durante un tiempo, y recientemente comencé a usarlo para etiquetar mis lanzamientos para poder hacer un seguimiento más fácil de los cambios y poder ver qué versión están ejecutando cada uno de nuestros clientes (desafortunadamente el código actualmente exige que cada cliente tiene su propia copia del sitio PHP; estoy cambiando esto, pero es lento).

En cualquier caso, estamos comenzando a generar algo de impulso, pensé que sería realmente bueno poder mostrarle a la gente lo que ha cambiado desde el último lanzamiento. El problema es que no he mantenido un registro de cambios porque no tengo una buena idea de cómo hacerlo. Para este momento en particular, puedo ejecutar el registro y crear uno manualmente, pero eso se cansará muy rápidamente.

Intenté buscar en Google "git changelog" y "git manage changelog", pero no encontré nada que realmente hablara sobre el flujo de trabajo de los cambios de código y cómo eso coincide con el registro de cambios. Actualmente estamos siguiendo el flujo de trabajo de desarrollo de Rein Henrichs y me encantaría algo que acompañara a eso.

¿Existe un enfoque estándar que me estoy perdiendo o es un área en la que todos hacen lo suyo?

Muchas gracias por sus comentarios / respuestas!

Topher Fangio
fuente

Respuestas:

181

Esto fue hace unos 3-4 años, pero por el bien de los futuros buscadores, ahora es posible generar registros magníficos con:

git log --oneline --decorate

O, si lo quieres aún más bonito (con color para terminal):

git log --oneline --decorate --color

La canalización de esa salida a ChangeLog es lo que uso actualmente en todos mis proyectos, es simplemente increíble.


fuente
44
Otra etiqueta útil es --graph, que muestra visualmente en qué ramas están las confirmaciones.
Eruant
44
Recomiendo encarecidamente que no se utilicen los diferenciales de registro de regalos como CHANGELOG: keepachangelog.com
Olivier Lacan
44
copiar la git logsalida al registro de cambios no tiene sentido. Necesita hacer un trabajo de filtrado y edición para tener un registro de cambios legible, de lo contrario, ¿por qué necesitaría un registro de cambios? Creo que puede automatizar la generación de un registro de cambios, ¡pero no haga una copia en bruto de git log!
vaab
19
El problema con esto es que, incluso suponiendo que cada contribuyente a su proyecto escriba mensajes de confirmación claros y legibles, seguirá generando un "registro de cambios" que contiene TONELADAS de ruido. Los registros de cambios deben escribirse con el objetivo de explicar a los usuarios de su proyecto los cambios notables relevantes para ellos que ocurrieron entre lanzamientos, mientras que los mensajes de confirmación deben centrarse en explicar a los desarrolladores qué mejoras realiza su confirmación en el código . A veces hay superposición allí, pero no siempre.
Ajedi32
77
O, para hacerlo un poco más concreto, este método creará un "registro de cambios" que contiene muchas entradas como "Ortografía fija de fooMethod en ZModule" y "Refactor XModule para usar una nueva versión de XYLibarary". Sus usuarios no se preocupan por eso. Quieren saber qué cambios se hicieron desde su perspectiva como usuarios, no desde su perspectiva como desarrollador. Y eso incluso ignora cosas como "Combinar PR # 123 de xdev / foo" y "Opps, arreglado newFeature para que realmente funcione", cosas que probablemente existan en cualquier repositorio del mundo real.
Ajedi32
60

Puedes usar un poco de sabor de git log para ayudarte:

git log --pretty=%s                 # only print the subject

Si nombra sus ramas muy bien, de modo que una combinación de master se muestre como algo así como "Función de rama combinada-foobar", puede acortar las cosas solo mostrando ese mensaje, y no todas las pequeñas confirmaciones que combinó, que juntas forman el característica:

git log --pretty=%s --first-parent  # only follow first parent of merges

Es posible que pueda aumentar esto con un script propio, que podría hacer cosas como eliminar los bits de "Rama fusionada", normalizar el formato, etc. Sin embargo, en algún momento debe escribirlo usted mismo, por supuesto.

Luego, podría crear una nueva sección para el registro de cambios una vez por versión:

git log [opts] vX.X.X..vX.X.Y | helper-script > changelogs/X.X.Y

y confirme eso en su versión de lanzamiento de confirmación.

Si su problema es que esos temas de compromiso no se parecen en nada a lo que le gustaría poner en un registro de cambios, tiene dos opciones: seguir haciendo todo manualmente (e intentar mantenerse al día con más frecuencia en lugar de jugar catch- en el momento del lanzamiento), o arregle su estilo de mensaje de confirmación. Una opción, si los sujetos no lo van a hacer por usted, sería colocar líneas como "cambio: función adicional foobar" en los cuerpos de sus mensajes de confirmación, para que luego pueda hacer algo como git log --pretty=%B | grep ^change:capturar solo esos súper - bits importantes de los mensajes.

No estoy completamente seguro de cuánto más que ese git realmente podría ayudarlo a crear sus registros de cambios. ¿Tal vez he malinterpretado lo que quieres decir con "administrar"?

Cascabel
fuente
2
Definitivamente es un gran comienzo, y no había pensado en agregar un modificador al cuerpo para poder agarrarlo más tarde. Eso puede ser lo que termino haciendo. ¡Gracias por la respuesta! Si no llegan más respuestas al día siguiente, marcaré la suya como la respuesta :-)
Topher Fangio
60

DESCARGO DE RESPONSABILIDAD: Soy el autor de gitchangelog del que hablaré a continuación.

TL; DR: es posible que desee comprobar el registro de cambios propio de gitchangelog o la salida ascii que generó el anterior.

Si desea generar un registro de cambios a partir de su historial de git, probablemente tenga que considerar:

  • El formato de salida . (Puro ASCII personalizado, tipo de registro de cambios de Debian, Markdow, ReST ...)
  • algunos filtros de confirmación (es probable que no desee ver todos los errores tipográficos o cosméticos que aparecen en su registro de cambios)
  • algunos confirman las disputas de texto antes de ser incluidas en el registro de cambios. (Garantizar la normalización de los mensajes con una primera letra en mayúscula o un punto final, pero también podría eliminar algún marcado especial en el resumen)
  • ¿Es compatible tu historial de git ? La fusión, el etiquetado, no siempre es tan fácil de soportar por la mayoría de las herramientas. Depende de cómo gestiones tu historial.

Opcionalmente, es posible que desee alguna categorización (cosas nuevas, cambios, correcciones de errores) ...

Con todo esto en mente, creé y utilizo gitchangelog . Está destinado a aprovechar una convención de mensajes de compromiso de git para lograr todos los objetivos anteriores.

Tener una convención de mensajes de compromiso es obligatorio para crear un buen registro de cambios (con o sin usar gitchangelog).

convención de mensaje de compromiso

Las siguientes son sugerencias de lo que podría ser útil pensar en agregar en sus mensajes de confirmación.

Es posible que desee separar aproximadamente sus confirmaciones en grandes secciones:

  • por intención (por ejemplo: nuevo, arreglar, cambiar ...)
  • por objeto (por ejemplo: doc, packaging, código ...)
  • por audiencia (por ejemplo: dev, tester, usuarios ...)

Además, es posible que desee etiquetar algunas confirmaciones:

  • como confirmaciones "menores" que no deberían quedar desactualizadas en su registro de cambios (cambios cosméticos, pequeños errores tipográficos en los comentarios ...)
  • como "refactor" si realmente no tiene ningún cambio significativo en las características. Por lo tanto, esto no debería ser también parte del registro de cambios que se muestra al usuario final, por ejemplo, pero podría ser de algún interés si tiene un registro de cambios de desarrollador.
  • también puede etiquetar con "api" para marcar cambios en la API o cosas nuevas de la API ...
  • ... etc ...

Intente escribir su mensaje de confirmación dirigiéndose a los usuarios (funcionalidad) con la mayor frecuencia posible.

ejemplo

Esto es estándar git log --onelinepara mostrar cómo se puede almacenar esta información ::

* 5a39f73 fix: encoding issues with non-ascii chars.
* a60d77a new: pkg: added ``.travis.yml`` for automated tests. 
* 57129ba new: much greater performance on big repository by issuing only one shell command for all the commits. (fixes #7)
* 6b4b267 chg: dev: refactored out the formatting characters from GIT.
* 197b069 new: dev: reverse ``natural`` order to get reverse chronological order by default. !refactor 
* 6b891bc new: add utf-8 encoding declaration !minor 

Entonces, si te has dado cuenta, el formato que elegí es:

{new|chg|fix}: [{dev|pkg}:] COMMIT_MESSAGE [!{minor|refactor} ... ]

Para ver un resultado de salida real, puede mirar al final de la página PyPI de gitchangelog

Para ver una documentación completa de mi convención de mensajes de confirmación, puede ver el archivo de referencia gitchangelog.rc.reference

Cómo generar un registro de cambios exquisito a partir de esto

Entonces, es bastante fácil hacer un registro de cambios completo. Podrías hacer tu propio script bastante rápido o usarlo gitchangelog.

gitchangeloggenerará un registro de cambios completo (con soporte de seccionamiento como New, Fix...), y es razonablemente configurable para sus propias convenciones de compromiso. Es compatible con cualquier tipo de producción gracias a templating a través Mustache, Mako templatingy tiene un motor de herencia predeterminado escrito en Python prima; Todos los 3 motores actuales tienen ejemplos de cómo usarlos y pueden generar registros de cambios como el que se muestra en la página PyPI de gitchangelog.

Estoy seguro de que sé que hay un montón de otros git loga changelogherramientas por ahí también.

vaab
fuente
1
Esto es increíble, exactamente lo que estaba buscando. Probaré esto, ¡muchas gracias!
Jeff Kiiza
26

Un cambio más al punto. Dime si a ustedes les gusta.

git log --since=1/11/2011 --until=28/11/2011 --no-merges --format=%B
Harshniket Seta
fuente
Esto lo hace un poco: agregaría otros parámetros --format, como se explica en git-scm.com/docs/git-log#_pretty_formats
bluesmonk el
23

El gitlog-to-changelogscript es útil para generar un estilo GNU ChangeLog.

Como se muestra gitlog-to-changelog --help, puede seleccionar las confirmaciones utilizadas para generar un ChangeLogarchivo con la opción --since:

gitlog-to-changelog --since=2008-01-01 > ChangeLog

o pasando argumentos adicionales después --, que serán pasados ​​a git-log(llamados internamente por gitlog-to-changelog):

gitlog-to-changelog -- -n 5 foo > last-5-commits-to-branch-foo

Por ejemplo, estoy usando la siguiente regla en el nivel superior Makefile.amde uno de mis proyectos:

.PHONY: update-ChangeLog
update-ChangeLog:
    if test -d $(srcdir)/.git; then                         \
       $(srcdir)/build-aux/gitlog-to-changelog              \
          --format='%s%n%n%b%n' --no-cluster                \
          --strip-tab --strip-cherry-pick                   \
          -- $$(cat $(srcdir)/.last-cl-gen)..               \
        >ChangeLog.tmp                                      \
      && git rev-list -n 1 HEAD >.last-cl-gen.tmp           \
      && (echo; cat $(srcdir)/ChangeLog) >>ChangeLog.tmp    \
      && mv -f ChangeLog.tmp $(srcdir)/ChangeLog            \
      && mv -f .last-cl-gen.tmp $(srcdir)/.last-cl-gen      \
      && rm -f ChangeLog.tmp;                               \
    fi

EXTRA_DIST += .last-cl-gen

Esta regla se usa en el momento del lanzamiento para actualizar ChangeLogcon los últimos mensajes de confirmación aún no grabados. El archivo .last-cl-gencontiene el identificador SHA1 de la última confirmación registrada ChangeLogy se almacena en el repositorio de Git. ChangeLogtambién se registra en el repositorio, para que pueda editarse (por ejemplo, para corregir errores tipográficos) sin alterar los mensajes de confirmación.

Roland Levillain
fuente
El script mklog de GCC también puede ser interesante: stackoverflow.com/a/31606865/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
¡Este debería ser el proyecto ganador! ¿Por qué no lo tienes en Github?
Omer Dagan el
20

Dado que la mejor práctica es crear una etiqueta por versión, es posible que desee particionar su registro de cambios por versión. En ese caso, este comando podría ayudarlo a:

git log YOUR_LAST_VERSION_TAG..HEAD --no-merges --format=%B
bithavoc
fuente
15

Para proyectos de GitHub podría ser útil: github-changelog-generator

Genera un registro de cambios a partir de problemas cerrados de etiquetas y solicitudes de extracción fusionadas.

Este CHANGELOG.md fue generado por este script.

Ejemplo:

Registro de cambios

1.2.5 (2015-01-15)

Registro de cambios completo

Mejoras implementadas:

  • Use hito para especificar en qué versión se corrigió el error # 22

Errores arreglados:

  • Error al intentar generar el registro para el repositorio sin etiquetas # 32

Solicitudes de extracción fusionadas:

  • La clase PrettyPrint se incluye usando minúsculas 'pp' # 43 ( schwing )

  • Soporta Enterprise Github a través de las opciones de línea de comando # 42 ( glenlovett )

skywinder
fuente
Tales proyectos son los mejores :) ¿Cuál fue su motivación para hacerlo? También gracias a su inspiración, hice una herramienta similar, que funciona sin etiquetas, se divide en Agregado / Modificado / Reparado / Eliminado y está en PHP (mi idioma "nativo"): github.com/Symplify/ChangelogLinker ¿Escribe publicaciones sobre Changlogs? ? Me gustaría leerlos
Tomáš Votruba
1
@ TomášVotruba gracias por sus cálidas palabras. Es solo mi hobby. No publiqué mucho. Pero creo que vale la pena. ¡Los mejores deseos!
skywinder
10

También hice una biblioteca para esto. Es totalmente configurable con una plantilla de bigote. Eso puede:

  • Se almacenará en un archivo, como CHANGELOG.md .
  • Ser publicado en MediaWiki
  • O simplemente imprímalo en STDOUT

También hice:

Más detalles sobre Github: https://github.com/tomasbjerre/git-changelog-lib

Desde la línea de comando:

npx git-changelog-command-line -std -tec "
# Changelog

Changelog for {{ownerName}} {{repoName}}.

{{#tags}}
## {{name}}
 {{#issues}}
  {{#hasIssue}}
   {{#hasLink}}
### {{name}} [{{issue}}]({{link}}) {{title}} {{#hasIssueType}} *{{issueType}}* {{/hasIssueType}} {{#hasLabels}} {{#labels}} *{{.}}* {{/labels}} {{/hasLabels}}
   {{/hasLink}}
   {{^hasLink}}
### {{name}} {{issue}} {{title}} {{#hasIssueType}} *{{issueType}}* {{/hasIssueType}} {{#hasLabels}} {{#labels}} *{{.}}* {{/labels}} {{/hasLabels}}
   {{/hasLink}}
  {{/hasIssue}}
  {{^hasIssue}}
### {{name}}
  {{/hasIssue}}

  {{#commits}}
**{{{messageTitle}}}**

{{#messageBodyItems}}
 * {{.}} 
{{/messageBodyItems}}

[{{hash}}](https://github.com/{{ownerName}}/{{repoName}}/commit/{{hash}}) {{authorName}} *{{commitTime}}*

  {{/commits}}

 {{/issues}}
{{/tags}}
"

O en Jenkins:

ingrese la descripción de la imagen aquí

Tomás Bjerre
fuente
3
git log --oneline --no-merges `git describe --abbrev=0 --tags`..HEAD | cut -c 9- | sort

Es lo que me gusta usar. Obtiene todos los commits desde la última etiqueta. cutse deshace del hash commit. Si usa números de ticket al comienzo de sus mensajes de confirmación, se agrupan con sort. También ayuda a clasificar Si el prefijo ciertas confirmaciones con fix, typo, etc.

orkoden
fuente
3

Dejo que el servidor CI canalice lo siguiente en un archivo con el nombre CHANGELOGde cada nueva versión con la fecha establecida en el nombre de archivo de la versión:

>git log --graph --all --date=relative --pretty=format:"%x09 %ad %d %s (%aN)"
Lorenz Lo Sauer
fuente
2

Para un registro de cambios de estilo GNU , he cocinado la función

gnuc() {
  {
    printf "$(date "+%Y-%m-%d")  John Doe  <[email protected]>\n\n"
    git diff-tree --no-commit-id --name-only -r HEAD | sed 's/^/\t* /'
  } | tee /dev/tty | xsel -b
}

Con este:

  • Confirmo mis cambios periódicamente para hacer una copia de seguridad y volver a crearlos antes de hacer la edición final en ChangeLog
  • entonces corre: gnuc

y ahora mi portapapeles contiene algo como:

2015-07-24  John Doe  <[email protected]>

        * gdb/python/py-linetable.c (): .
        * gdb/python/py-symtab.c (): .

Luego uso el portapapeles como punto de partida para actualizar ChangeLog.

No es perfecto (por ejemplo, archivos deben estar en relación con su trayectoria de registro de cambios, por lo que python/py-symtab.csin gdb/ya que voy a editar el gdb/ChangeLog), pero es un buen punto de partida.

Scripts más avanzados:

Sin embargo, tengo que estar de acuerdo con Tromey: duplicar los datos de confirmación de git en ChangeLog es inútil.

Si va a hacer un registro de cambios, haga un buen resumen de lo que está sucediendo, posiblemente como se especifica en http://keepachangelog.com/

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
2

Basado en bithavoc , enumera el last taghasta HEAD. Pero espero enumerar los registros entre 2 etiquetas.

// 2 or 3 dots between `YOUR_LAST_VERSION_TAG` and `HEAD`
git log YOUR_LAST_VERSION_TAG..HEAD --no-merges --format=%B

Lista de registros entre 2 etiquetas.

// 2 or 3 dots between 2 tags
git log FROM_TAG...TO_TAG

Por ejemplo, enumerará los registros de v1.0.0a v1.0.1.

git log v1.0.0...v1.0.1 --oneline --decorate

AechoLiu
fuente