Git Notes: la función más genial y más odiada de Git (2022)
(tylercipriani.com)- Git notes es una función para adjuntar metadatos en un espacio de nombres separado sin modificar los objetos de Git, pero no se usa de forma amplia debido a su baja usabilidad y adopción limitada
- Permite añadir información nueva sin tener que corregir mensajes de commit antiguos, por lo que encaja bien con registros que dejan sistemas automatizados, como información de revisiones, builds y tickets
- El proyecto Git y Gerrit usan notes en la práctica para poder ver en
git logdiscusiones de listas de correo, resultados de pruebas e información de revisores por commit - git-appraise de Google implementa revisión de código distribuida sobre git notes, lo que permite hacer solicitudes de revisión, comentarios, revisiones y merges desde local
- GitHub dejó de mostrar commit notes en 2014, y las notes para blob y tree requieren estar familiarizado con comandos internos de Git, así que siguen siendo difíciles de usar pese a su potencial para distribuir el historial del proyecto
Metadatos sin modificar objetos de Git
- Git notes es una función para guardar metadatos separados en los objetos que Git rastrea
- El objetivo incluye no solo commits, sino también blob y tree
- Adjunta información en un espacio de nombres separado sin modificar el objeto en sí
- Los mensajes de commit que ya entraron al historial normalmente no se pueden corregir de forma segura, pero con notes se puede añadir información nueva incluso a commits antiguos
- Por ejemplo, se puede agregar una nota con
git notes add -masí:git notes add -m 'Acked-by: <tyler@tylercipriani.com>' - Después aparece debajo de ese commit en
git logcomo un bloqueNotes:
- Por ejemplo, se puede agregar una nota con
- Scott Chacon escribió en GitHub.blog en 2010 que veía notes como una función más adecuada para adjuntar registros automatizados de tickets y sistemas de build que para conversaciones entre desarrolladores
Uso real y puntos donde se traba
- El proyecto Git usa notes para vincular cada commit con discusiones en listas de correo
- En el
Notes (amlog)del commit de ejemplo aparece unMessage-Id, y ese valor lleva al hilo de discusión del parche
- En el
- notes también se usa para rastrear tiempo de trabajo por commit o rama, añadir información de revisión y pruebas a
git log, y hasta para revisión de código totalmente distribuida - El plugin reviewnotes de Gerrit permite ver metadatos de revisión de código dentro de Git y sin conexión
- Los comandos para traer y mostrar notes son estos:
git fetch origin refs/notes/review:refs/notes/review git log --show-notes=review - Entre la información mostrada están
Verified+1,Verified+2,Code-Review+2,Submitted-by,Submitted-at,Reviewed-on,ProjectyBranch
- Los comandos para traer y mostrar notes son estos:
- git-appraise de Google es un sistema de “fully distributed code review” construido sobre git notes
- Funciona de manera independiente de code forges como GitHub o GitLab
- Permite hacer solicitudes de revisión de cambios, comentarios sobre cambios, revisiones y merges desde la computadora local
- También incluye una interfaz web
- Su mayor debilidad es la usabilidad
- GitHub dejó de mostrar commit notes en 2014
- Las commit notes se pueden hacer algo más fáciles de usar con configuración en
gitconfigpara fetch automático y visualización engit loggit config --add \ remote.origin.fetch \ '+refs/notes/*:refs/notes/*' git config \ notes.displayRef \ 'refs/notes/*' - Para guardar notes en blob o tree hay que estar familiarizado con el plumbing de Git
- Git distribuye el historial del código, pero gran parte del valor de un repositorio Git queda encerrado dentro de forges como GitHub
- git notes podría ser una vía para distribuir no solo el código, sino el historial completo del proyecto
1 comentarios
Opiniones de Hacker News
Otra función poco conocida es git trailers: https://alchemists.io/articles/git_trailers
Son datos estructurados de clave-valor que se pueden incluir al crear commits, y algunos sistemas los usan para adjuntar metadatos. Por ejemplo, Gerrit usa esta función para agregar el Change-Id
Permite adjuntar texto a varios objetos de base de datos en PostgreSQL. Sería bueno que PostgreSQL también tuviera una función de metadatos de objetos de base de datos en formato clave-valor estructurado y editable
[skip ci], probablemente para que sea más fácil eliminarlo en los subsistemas que consumen mensajes de commit: https://docs.github.com/en/actions/managing-workflow-runs-an...No sé por qué obliga a que sea el último trailer; quizá sea por una expresión regular
Me resultó útil cuando trabajaba con un upstream open source y quería pulir perfectamente mi rama con
git rebase -i. Ahora me parece mejor poner esa información en git trailers. Sobre Change-Id, sería bueno que Git mismo tuviera identificadores así para que las herramientas pudieran entenderlos. Identificar commits por el mensaje de commit es frágil, sobre todo en MR, donde el mensaje puede cambiarse. El ID del commit identifica el commit de forma única, pero no es un identificador útil cuando el mismo cambio puede moverse sobre otro commit. Dicho eso, los trailers son parte del commit real y las notes no, así que para el uso que yo les daba no serían un buen reemplazoMe pregunto si ponerlos manualmente en el mensaje de commit y usar la bandera
--traileres funcionalmente lo mismoIntenté levantar una instancia local e integrarla con un repositorio alojado en GitHub, y solo terminé frustrado. Me pregunto si hay una alternativa que maneje mejor que GitHub cosas como el seguimiento de cambios entre commits, que esté desarrollándose más activamente y que también sea amigable con la integración con GitHub. Realmente odio las herramientas de revisión de código de GitHub
Forgejo también lo soporta desde la versión 10, lanzada en enero de este año: https://forgejo.org/2025-01-release-v10-0/#new-features
https://codeberg.org/forgejo/forgejo/pulls/4753
Se ve realmente genial, pero me pregunto cómo funcionan las notes junto con funciones de reescritura del historial que en la práctica reemplazan commits por copias modificadas, como amend o rebase
Parece que las notes se adjuntan a commits, trees o IDs de blobs específicos. Me pregunto si
git rebasey demás son lo bastante inteligentes como para copiar las notes a los commits nuevos, o si simplemente desaparecen. También me intriga qué pasa cuando en un rebase interactivo haces squash de varios commits en uno. Adjuntar notes a blobs y trees parece tener el mismo problema. Se siente como adjuntar metadatos a archivos o directorios del repositorio, pero en realidad se adjuntan a contenido específico. Por ejemplo, si le agregas una note a un blob que contiene la cadena"Hello world!", ¿Git asociará la note con todos los archivos que tengan ese contenido? Y si cambias un archivo a"Hello, world!", ¿perderás las notes?notes.rewriteengit-config(1)Llevo usando Git probablemente unos 10 años y no sabía que existía git notes. Genial
La petición de “que todos los forges hagan que los metadatos de revisión de código estén disponibles offline dentro de Git” probablemente no funcione muy bien con forges comerciales como GitHub. Como tú mismo dijiste, mucho del valor de los repositorios Git está encerrado en forges como GitHub. Las empresas con fines de lucro normalmente no tienen mucho interés en convertir en algo genérico su valor agregado. No intento criticar a GitHub; creo que lo hacen bien al ofrecer un excelente servicio y un nivel gratuito muy generoso, y al permitirte extraer todos tus datos mediante la API si quieres irte. Es simplemente la naturaleza de una operación comercial
Git notes solo es genial cuando se agrega texto con frecuencia después de que un commit ya fue creado y mostrado a otras personas
Los ejemplos de Acked-By y enlaces a discusiones en listas de correo no me parecen buenos. Es muy probable que ambos ya se conozcan al crear el commit. Los mensajes de commit de Git prácticamente no tienen límite de longitud, así que también se podría copiar tal cual en el propio mensaje del commit la discusión relacionada que ocurrió en el forge. Creo que un mejor ejemplo sería agregar una git note a un commit que luego fue revertido
Quizá yo sea raro, pero he visto demasiados colegas que no miran bien los comentarios ni el annotate para recordar por qué se escribió el código originalmente. Simplemente lo cambian de golpe y esperan que el problema no quede asociado a ellos. Pero después de tratar con clientes enojados que estaban esperando una corrección de bug, y de ver cómo ese bug vuelve a aparecer poco después, uno puede volverse más cuidadoso con las correcciones de bugs. Para corregir varios bugs de una sola vez muchas veces hace falta refactorizar, y la refactorización también puede abrir oportunidades para nuevas funcionalidades o mejoras de rendimiento
Para dejar una marca en un commit que luego fue revertido, el mensaje de commit es mejor. Si se hace blame sobre un archivo, se ven los cambios más recientes de ese archivo, y si un commit revirtió los cambios de otro commit, el commit de reversión más reciente aparece en el blame
Esto no es falta de conocimiento, es un problema de UI. Si la UI de GitHub mostrara notes, su uso aumentaría muchísimo de inmediato
Hay muchas “funciones más geniales pero menos queridas de Git”. Por ejemplo bisect, pickaxe, reflog, range-diff, archive, tags anotados, etc.
Es una lástima que estas funciones se olviden con frecuencia porque mucha gente piensa en Git apenas como una especie de Google Drive vistoso
Aun así me parece bien. La filosofía Unix es enfocarse en una sola cosa y hacerla bien
En el proyecto LibreOffice se usaron Git notes para rastrear cada commit del repositorio de Apache OpenOffice
Al espejar ese repositorio como una rama del repositorio Git de LibreOffice, registraban si cada commit era un cambio irrelevante —por ejemplo, un cambio en el sistema de build que LibreOffice ya había reemplazado hace mucho por algo mejor—, si era duplicado de un cambio que ya existía en LibreOffice, o, en casos raros, si fue aceptado en LibreOffice y con qué commit se le hizo cherry-pick. Todavía se puede ver directamente en https://cgit.freedesktop.org/libreoffice/core/log/?h=aoo/tru..., y este frontend de Git todavía muestra notes. Desde hace algunos años dejaron de hacer este seguimiento de cambios, probablemente porque el ritmo de cambios de Apache OpenOffice se volvió muy lento y ya no había mucho beneficio en hacer cherry-pick de los pocos cambios disponibles
No es la función más genial pero menos querida, sino más bien una función gimmick que podría haber sido genial en casos muy específicos, como un equipo donde toda la empresa está compuesta solo por desarrolladores
Lo necesario va en el mensaje del commit, y referenciar tickets en un sistema separado no es un bug sino una funcionalidad. Porque JIRA u otros sistemas se usan para comunicarse con personas que no son desarrolladoras. Por ejemplo, un analista de negocio no tiene ningún acceso al código ni al repositorio, y el personal de soporte tampoco tiene acceso al repositorio ni al código. Se podría crear un frontend para que personas no desarrolladoras vean y editen notes, pero aun así no tendría mucho sentido. Los BA, soporte, etc., no están interesados en commits específicos; una funcionalidad puede coincidir exactamente con un único commit, pero normalmente no es así. Si se usan varios repositorios y una funcionalidad atraviesa varios servicios, git notes se vuelve bastante inútil, y al final hace falta una referencia a un sistema externo
Pero eso es lo dominante. A veces un analista de otro equipo que comparte el mismo monorepo me hace una pregunta que podría responderse de inmediato con una línea de código. Ese analista es bastante técnico e incluso sabe SQL, y nuestro código está escrito de forma muy idiomática y de alto nivel. Aun así, la cultura no puede cambiar por sí sola hasta que muere por sus ineficiencias inherentes
[^1] https://news.ycombinator.com/item?id=44348438
Se cerró recientemente una solicitud de funcionalidad de hace 9 años para que GitLab soporte notes: https://gitlab.com/gitlab-org/gitlab/-/issues/15029
Lamentablemente hay que iniciar sesión para leerla, pero debería bastar con cualquier cuenta de gitlab.com