¿Cómo usar git-notes en git? Guía completa para desarrolladores

Git incluye una funcionalidad poco conocida llamada git-notes que permite adjuntar metadatos a commits existentes u otros objetos sin modificar su historial.

En proyectos reales suele existir información adicional que no forma parte del commit original, por ejemplo:

  • Referencias a bugs
  • Resultados de integración continua (CI)
  • Revisiones de código
  • Métricas de calidad
  • Auditorías o anotaciones internas

Modificar el mensaje del commit para añadir esta información implicaría reescribir el historial, algo que puede romper flujos de trabajo o causar problemas en repositorios compartidos.

Aquí es donde entran en juego git-notes. En este artículo aprenderás ¿cómo usar git-notes en git? para añadir anotaciones a tus commits sin modificar el historial, mejorando la trazabilidad y colaboración en tus proyectos.

¿Qué son las git-notes?

Las git-notes son anotaciones que pueden añadirse a cualquier objeto de git, aunque el caso más habitual es anotar commits existentes.

A diferencia de modificar el mensaje de un commit, las git-notes se almacenan de forma separada del objeto original. Esto tiene varias implicaciones importantes:

  • El hash del commit no cambia
  • El historial del repositorio permanece intacto
  • Las notas pueden compartirse o no entre repositorios

Por defecto, Git almacena estas anotaciones en el namespace:

refs/notes/commits

Cada nota se asocia al hash del objeto anotado, lo que permite relacionar fácilmente commits con su metadata sin modificar el contenido original del repositorio.

La historia detrás de git-notes

Las git-notes nacieron para resolver un problema muy concreto: añadir información adicional a commits sin alterar su identidad criptográfica.

En Git, cada commit se identifica mediante un hash SHA, generado a partir de su contenido y metadatos. Si modificas el mensaje del commit o cualquiera de sus metadatos, el hash cambia y se crea un commit completamente distinto.

Esto complica tareas habituales como:

  • Añadir resultados de CI a commits ya publicados
  • Asociar revisiones de código posteriores
  • Adjuntar información generada automáticamente por herramientas

La idea original fue propuesta en 2007 por Johan Herland en la mailing list de Git. Su diseño estaba inspirado en herramientas como StGit, que permitían gestionar metadatos asociados a parches. Con el tiempo, la propuesta evolucionó hasta integrarse en el propio Git. Los principales autores de la implementación en el núcleo de Git fueron Johan Herland y Johannes Schindelin.

¿Cómo funcionan internamente las git-notes?

Para entender cómo funcionan las git-notes, conviene revisar primero cómo Git almacena la información internamente.

Git guarda todos los datos como objetos:

  • blobs → contenido de archivos
  • trees → estructura de directorios
  • commits → snapshots del proyecto

Cada objeto está identificado por un hash SHA y se almacena en la base de datos interna del repositorio.

Las git-notes reutilizan exactamente esta misma infraestructura.

Estructura interna

Cuando ejecutas:

git notes add -m "Internal note"

Git realiza internamente los siguientes pasos:

  1. crea un blob con el contenido de la git-note
  2. actualiza la estructura de directorios (tree) de la git-note
  3. crea un commit en la referencia al git-note

Cada modificación genera un nuevo commit en:

refs/notes/commits

Por lo tanto, incluso las git-notes tienen su propio historial, que puede consultarse con:

git log -p refs/notes/commits

Esto permite saber cuándo se añadieron o modificaron las notas dentro del repositorio.

Organización de la estructura de diretorios (tree) de git-notes

Dentro de la estructura de directorios, los nombres de archivo corresponden al hash del objeto anotado.

Esto crea una relación directa entre un commit y su git-note, ya que cada entrada en la estructura de directorios utiliza el hash del objeto como identificador.

En otras palabras, Git mantiene un mapa entre commits y git-notes, donde el hash del commit apunta al blob que contiene el texto de la anotación.

Un ejemplo simplificado de esta estructura sería:

refs/notes/commits
└── tree
├── a1b2c3d4... -> blob (git-note)
├── f9e8d7c6... -> blob (git-note)

En esta estructura de directorios:

  • a1b2c3d4... representa el hash de un commit
  • el blob asociado contiene el texto de la git-note

Gracias a esta estructura, Git puede recuperar rápidamente los git-notes asociados a cualquier objeto sin modificar el commit original.

Usando git-notes

Veamos un escenario real:

Imagina que trabajas en un proyecto donde cada commit debe pasar por:

  • un pipeline de CI
  • una revisión de código
  • una verificación de seguridad

Modificar el mensaje del commit para incluir esta información no es recomendable, porque:

  • Cambia el hash del commit, generando un nuevo commit distinto
  • Rompe el historial compartido, afectando a otros colaboradores
  • Puede impactar ramas ya publicadas y complicar merges

En lugar de modificar el commit, podemos usar git-notes para almacenar metadatos adicionales sin alterar el historial principal.
Esto permite documentar resultados de CI, revisiones y auditorías directamente asociados a cada commit, manteniendo intacto su contenido original.

Ejemplo

Partamos de un repositorio simple para ver cómo usar git-notes en la práctica.

Primero creamos un repositorio y añadimos un archivo:

cd /tmp
git init notes-demo
cd notes-demo
echo "console.log('hello')" > app.js
git add app.js
git commit -m "Add initial application"

Ahora verificamos el historial del repositorio:

git log --oneline

Salida:

44224f9 (HEAD -> master) Add initial application

Este será el commit sobre el que añadiremos nuestras primeras git-notes.

Agregar una git-note a un commit

Supongamos que el sistema de CI ejecuta pruebas sobre este commit y queremos guardar el resultado asociado a él.

Podemos hacerlo con:

git notes add -m "CI: tests passed"

Este comando añade una git-note al commit actual (HEAD).

Para ver la git-note asociada al commit podemos usar:

git notes show

Salida:

CI: tests passed

También podemos visualizar la git-note directamente en el historial de commits ejecutando:

git log --show-notes

Git mostrará algo similar a esto:

commit 44224f9654ca62bbbffae888bf727f25104e3f3c (HEAD -> master)
Author: ...
Date: ...

Add initial application

Notes:
CI: tests passed

De esta forma podemos añadir información útil a los commits sin modificar su contenido original ni alterar su hash.

Añadir git-notes desde archivos

En muchos casos, la información que queremos asociar a un commit no se escribe manualmente, sino que proviene de herramientas automáticas, por ejemplo reportes de tests o resultados de CI.

Primero creamos un archivo con el reporte:

echo "CI Results
Unit tests: OK
Lint: OK
Coverage: 87%" > ci-report.txt

Ahora intentamos añadir esta información como una git-note:

git notes add -F ci-report.txt

Git mostrará un error similar a este:

error: Cannot add notes. Found existing notes for object 44224f9654ca62bbbffae888bf727f25104e3f3c. Use '-f' to overwrite existing notes

Esto ocurre porque el commit ya tiene una git-note asociada.

Por defecto, git notes add no sobrescribe notas existentes para evitar perder información accidentalmente. Si realmente quieres reemplazar la nota actual, puedes usar la opción -f (force).

Editar un git-note

Si un commit ya tiene una nota asociada, podemos editarla directamente con:

git notes edit

Git abrirá el editor configurado en el repositorio con el contenido actual de la nota:

CI: tests passed

Podemos modificarla para añadir más información. Por ejemplo:

CI Results
Tests: OK
Coverage: 87%
Pipeline: success

Guardamos el archivo y cerramos el editor.
Git actualizará automáticamente la git-note asociada al commit.

Si ahora consultamos el historial con:

git log --show-notes

Veremos algo como:

commit 44224f9654ca62bbbffae888bf727f25104e3f3c (HEAD -> master)
Author: ...
Date: ...

    Add initial application

Notes:
CI Results
Tests: OK
Coverage: 87%
Pipeline: success

De esta forma podemos enriquecer las anotaciones asociadas a un commit sin modificar su historial ni su hash.

Agregar mas información a un git-note existente

Si queremos añadir más información a una git-note sin reemplazar su contenido, podemos usar el comando append.

git notes append -m "Review: approved by Alice"

Este comando agrega el nuevo texto al final de la nota existente, en lugar de sobrescribirla.

Si ahora consultamos el historial con:

git log --show-notes

Obtendremos algo similar a:

commit 44224f9654ca62bbbffae888bf727f25104e3f3c (HEAD -> master)
Author: ...
Date: ...

    Add initial application

Notes:
    CI Results
    Tests: OK
    Coverage: 87%
    Pipeline: success
    
    Review: approved by Alice

Este comando es especialmente útil cuando diferentes herramientas o procesos agregan información al mismo commit, por ejemplo:

  • pipelines de CI
  • sistemas de code review
  • auditorías de seguridad
  • herramientas de análisis estático

Cada sistema puede añadir su propia metadata sin interferir con las notas existentes.

Agregar git-notes a commits específicos

También es posible añadir git-notes a commits antiguos, no solo al commit actual.

Primero obtenemos el hash del commit:

git log --oneline

Salida típica:

44224f9 (HEAD -> master) Add initial application

Después añadimos la nota indicando el hash del commit. Por ejemplo:

git notes add -m "Security audit: passed" 44224f9

De esta forma podemos enriquecer commits históricos con información adicional, incluso mucho tiempo después de haber sido creados.

Este enfoque resulta especialmente útil para:

  • Documentación técnica asociada a cambios antiguos
  • Auditorías de seguridad posteriores
  • Resultados de herramientas automáticas
  • Referencias a incidencias detectadas más tarde

Ver todas las git-notes del repositorio

Para ver qué commits tienen git-notes asociadas, podemos usar:

git notes list

Este comando muestra una lista de las notas almacenadas en el repositorio junto con el hash del objeto al que están asociadas.

Si queremos ver las notas directamente dentro del historial de commits, podemos ejecutar:

git log --show-notes

De esta forma, Git mostrará las git-notes junto al mensaje de cada commit, lo que facilita entender el contexto de los cambios.

También es posible configurar Git para que muestre siempre las notes automáticamente al ejecutar git log:

git config --global notes.displayRef refs/notes/commits

Git mostrará siempre las git-notes del namespace refs/notes/commits al consultar el historial.

Por ejemplo, al ejecutar:

git log

Veremos algo como:

commit 44224f9654ca62bbbffae888bf727f25104e3f3c (HEAD -> master)
Author: ...
Date: ...

Add initial application

Notes:
CI Results
Tests: OK
Coverage: 87%
Pipeline: success

Review: approved by Alice

Ventajas de esta configuración:

  • No hace falta añadir --show-notes cada vez que consultamos el historial.
  • Permite ver automáticamente el contexto y metadatos de los commits.
  • Mantiene intacto el historial principal del repositorio, ya que las notas están en un namespace separado.

Eliminar un git-note

Si una git-note deja de ser relevante o ya no necesitamos la información que contiene, podemos eliminarla con:

git notes remove

Esto eliminará la nota asociada al commit actual (HEAD).

Si luego intentamos mostrarla:

git notes show

Git mostrará un mensaje como:

error: no note found for object 44224f9654ca62bbbffae888bf727f25104e3f3c

Es importante notar que solo se elimina la nota, mientras que el commit original permanece intacto.
El hash del commit no cambia, y el historial del repositorio sigue siendo el mismo.

Los namespaces de git-notes

Uno de los aspectos más potentes de git-notes es que soportan namespaces independientes.

Esto permite organizar distintos tipos de metadatos sin mezclarlos, por ejemplo separar notas de CI, revisiones de código o auditorías de seguridad.

Añadir una git-note en otro namespace

git notes --ref=bugs add -m "Bug #123 fixed"

Mostrar la nota en ese namespace

git notes --ref=bugs show

Listar todos los namespaces de notas

git for-each-ref refs/notes

Sincronizar git-notes entre repositorios

Al igual que las ramas, las git-notes pueden sincronizarse entre repositorios, lo que permite compartir metadatos sin alterar los commits originales.

Enviar notas a un repositorio remoto

git push origin refs/notes/*

Traer notas desde un repositorio remoto

git fetch origin refs/notes/*:refs/notes/*

Fusionar notas manualmente. Si existen notas diferentes en repositorios distintos, podemos fusionarlas con:

git notes merge <notes-ref>

Estrategias de merge disponibles

EstrategiaDescripción
manualResolución manual, crea un workspace temporal
oursPrioriza notas locales
theirsPrioriza notas remotas
unionConcatena notas de ambos repos
cat_sort_uniqConcatena y elimina duplicados

Por defecto, git usa la estrategia manual, que permite resolver conflictos de git-notes sin sobrescribir información importante.

Esto hace que las git-notes sean fácilmente colaborativas, ideales para equipos que comparten metadatos de CI, revisiones o auditorías.

Buenas prácticas

Si decides implementar git-notes en un equipo, conviene seguir algunas reglas para mantener el sistema ordenado y seguro.

1. Define namespaces claros

Organiza los metadatos en namespaces independientes para evitar confusión y facilitar la automatización. Por ejemplo:

refs/notes/ci       # estado de builds
refs/notes/review # comentarios de revisión
refs/notes/security # auditorías de seguridad

2. Evita datos sensibles

Ten en cuenta que las git-notes pueden compartirse con otros repositorios.
No incluyas información confidencial o contraseñas en las notas.

3. Automatiza su uso

Las git-notes se integran muy bien con flujos automatizados, por ejemplo:

  • hooks de Git para añadir notas al hacer commits
  • pipelines de CI para registrar resultados de tests o builds
  • herramientas internas que generan métricas, revisiones o auditorías

Automatizar el proceso reduce errores humanos y asegura que todas las notas se mantengan actualizadas y consistentes.

Conclusión

Las git-notes son una funcionalidad potente, aunque poco utilizada, que permite añadir metadatos a commits sin modificar el historial.

Gracias a su diseño:

  • el hash del commit permanece intacto
  • los metadatos se almacenan por separado
  • se pueden organizar mediante namespaces
  • pueden sincronizarse entre repositorios

Esto las convierte en una herramienta muy útil para:

  • pipelines de CI
  • sistemas de revisión de código
  • auditorías de seguridad
  • anotaciones internas y documentación técnica

Si necesitas añadir contexto al historial de Git sin reescribir commits, git-notes ofrece una solución elegante, flexible y segura, ideal para equipos y proyectos que requieren trazabilidad y enriquecimiento del historial de manera colaborativa.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *