-- Leo's gemini proxy
-- Connecting to gmi.osiux.com:1965...
-- Connected
-- Sending request
-- Meta line: 20 text/gemini;lang=es_AR
AUTHOR: Osiris Alejandro Gomez
EMAIL: osiux@osiux.com
DATE: 2022-11-21 23:15
[1]
Desde que comencé a usar `git` ^1[2] que mayormente los mensajes de *commit* los escribo en inglés, en parte porque resultan mas cortos y también porque es más simple relacionarlo a conceptos técnicos inherentes al código.
Desde 2008 que además agrego el tiempo consumido de cada *commit* con el formato `@ HH:MM hs` en la última línea, para llevar un registro de las horas trabajadas en cada proyecto.
Dependiendo del proyecto, a veces se incluye en el mensaje una referencia a uno o mas *issues* relacionados con formato `FIX #1234` o `REL #1234`.
Si el *issuetracker* no es de acceso público no le veo mucho sentido relacionar el *issue*, salvo que código y *bugtracker* sean *repos* privados. En general, prefiero en el *issue* relacionar los *commits* asociados, pero cada proyecto tiene sus particularidades, no hay una única regla.
Sin dudas, la dificultad esta en qué escribir como resumen? Obviamente hay que evitar mensajes como los siguientes:
`general refactor`
`update foo`
`add bar`
`fix bla`
Hace varios años que venía usando un *template* definido en `~/.gitconfig` de la siguiente manera:
[commit] template = /home/osiris/.gitmessage
El contenido del archivo `~/.gitmessage` es bastante claro y esta basado en el *post* `How to Write a Git Commit Message` ^2[3]
# prefix: imperative summary < 50 chars # # Remember blank line between title and body. # Explain *what* and *why* (not *how*). # Wrap at 72 chars # # Include task ID # REL #1234 # FIX #1234 # # How to Write a Git Commit Message: # https://chris.beams.io/posts/git-commit/ # # Include Task Time! # # @ 00:05 hs
Y ha sido de gran ayuda para no olvidar lo esencial a la hora de escribir el mensaje de un *commit*, pero ****no es mas que un recordatorio****
En otro intento por automatizar ^3[4] y reducir el tiempo de escritura de un mensaje de *commit* y que sea algo útil a futuro, se me ocurrió generar un *script* que se ocupe de armar un template dinámico, es decir, autocompleta todo lo que puede, acelerando el proceso y normalizando los mensajes de *commit*, más aún cuando se trata de *commits* atómicos y muy similares.
Es decir, al ejecutar `git-commit-message` ^4[5] dentro del directorio de un repositorio *git*, se a a generar el siguiente mensaje:
use git-remote-geturl to prevent leak tokens @ 00:09 hs
De dónde salió el *Subject*?, simplemente copia el último *subject* ya que si estás realizando *commits* atómicos y/o tareas similares, es muy probable que puedas reutilizarlo y de no servir, lo reescribís, similar al *template* estático.
Además se agregó el tiempo gastado? Se calcula de 2 posibles maneras:
1. Si el último *commit* es de hoy, se calcula la diferencia de tiempo.
2. Caso contrario se usa el tiempo de último *journal* ^5[6]
Si no están dadas las condiciones *a* y *b* se obtiene `@ 00:00 hs`, nuevamente como el *template* estático.
Ahora bien, si en lugar de ejecutar `git-commit-message` en una consola, lo hacemos desde `vim` ^6[7] en el momento en que *git* nos solicita ingresar el mensaje, el *script* detecta el archivo que se esta por *commitear*, por ejemplo el archivo `test.txt` y lo utiliza como prefijo (sin extensión) similar a *Conventional Commits*.
test: use git-remote-geturl to prevent leak tokens @ 00:09 hs
Y si el archivo estuviese en un directorio, por ejemplo `doc/test.txt`, el resultando sería el siguiente:
doc/test: use git-remote-geturl to prevent leak tokens @ 00:09 hs
De esta manera `git-commit-message` en parte normaliza la estructura de los mensajes y al mismo tiempo simplifica el proceso de escritura.
Para evitar invocar `:r!git-commit-message` constantemente, definí algunas teclas rápidas para ni siquiera tener que recordar el comando, simplemente basta con presionar una o más teclas de función.
┌───────┬──────────────────────────────────────────────────────────────────────┐ │ *Key* │ *Action* │ ╞═══════╪══════════════════════════════════════════════════════════════════════╡ │ `F3` │ agrega *filename: las commit subject* en línea 1 y tiempo en formato │ │ │ `@ 00:03 hs` en línea 3 │ ├───────┼──────────────────────────────────────────────────────────────────────┤ │ `F4` │ elimina todo desde línea 4 │ ├───────┼──────────────────────────────────────────────────────────────────────┤ │ `F5` │ agrega la salida de `git diff --staged` a partir de la última línea │ ├───────┼──────────────────────────────────────────────────────────────────────┤ │ `F6` │ agrega tiempo en formato `@ 00:03 hs` en línea 3 │ └───────┴──────────────────────────────────────────────────────────────────────┘
Algo muy piola de `vim` es la posibilidad de (re)definir acciones en las teclas de Función para un tipo y/o formato de archivo de manera muy simple, basta con indicar parte del nombre del archivo, en este caso `.git/COMMIT_EDITMSG` y mapear una tecla a una secuencia de comandos, por ejemplo:
" git commit message au BufNewFile,BufRead *.git/COMMIT_EDITMSG* map <F3> :1<CR>:r!git-commit-message<CR>ggddww au BufNewFile,BufRead *.git/COMMIT_EDITMSG* map <F4> :4<CR>VGd$ au BufNewFile,BufRead *.git/COMMIT_EDITMSG* map <F5> :$<CR>$:r!git diff --staged<CR> au BufNewFile,BufRead *.git/COMMIT_EDITMSG* map <F6> :2<CR>:r!git-last-timemsg<CR>
Presionando `F3` obtengo el mensaje de *commit* casi completo, es un *template* que contiene `prefijo: último mensaje de commit` y el tiempo consumido para este *commit*, calculando la diferencia de tiempo al último *commit* o tomando el tiempo transcurrido del último *journal*.
La secuencia de acciones es la siguiente:
┌─────────────────────────┬────────────────────────────────────────────────────┐ │ *command* │ *action* │ ╞═════════════════════════╪════════════════════════════════════════════════════╡ │ `:1` │ ir a la línea 1 │ ├─────────────────────────┼────────────────────────────────────────────────────┤ │ `<CR>` │ presionar *ENTER* │ ├─────────────────────────┼────────────────────────────────────────────────────┤ │ `:r!git-commit-message` │ ejecutar `git-commit-message` y escribir contenido │ ├─────────────────────────┼────────────────────────────────────────────────────┤ │ `<CR>` │ presionar *ENTER* │ ├─────────────────────────┼────────────────────────────────────────────────────┤ │ `gg` │ ir a la línea 1 en modo visual │ ├─────────────────────────┼────────────────────────────────────────────────────┤ │ `dd` │ borrar la primer línea │ ├─────────────────────────┼────────────────────────────────────────────────────┤ │ `ww` │ moverse 2 palabras (luego del prefijo) │ └─────────────────────────┴────────────────────────────────────────────────────┘
Presionando `F4` se eliminan todas las líneas a partir de la línea 4.
La secuencia de acciones es la siguiente:
┌───────────┬────────────────────────────────────────────────────────────────┐ │ *command* │ *action* │ ╞═══════════╪════════════════════════════════════════════════════════════════╡ │ `:4` │ ir a la línea 4 │ ├───────────┼────────────────────────────────────────────────────────────────┤ │ `<CR>` │ presionar *ENTER* │ ├───────────┼────────────────────────────────────────────────────────────────┤ │ `VGd$` │ seleccionar desde la línea actual hasta el final y eliminarlas │ └───────────┴────────────────────────────────────────────────────────────────┘
Presionando `F5` se agrega temporalmente la salida de `git diff --staged` al mensaje de *commit*, es muy útil para verificar qué se esta por versionar y al mismo tiempo sirve de inspiración para el *Subject* y permite autocompletar con el código mostrado.
La secuencia de acciones es la siguiente:
┌────────────────────────┬───────────────────────────────────────────────────┐ │ *command* │ *action* │ ╞════════════════════════╪═══════════════════════════════════════════════════╡ │ `:$` │ ir a la última línea │ ├────────────────────────┼───────────────────────────────────────────────────┤ │ `<CR>` │ presionar *ENTER* │ ├────────────────────────┼───────────────────────────────────────────────────┤ │ `$` │ ir al final de línea │ ├────────────────────────┼───────────────────────────────────────────────────┤ │ `:r!git diff --staged` │ ejecutar `git diff --staged` y escribir contenido │ ├────────────────────────┼───────────────────────────────────────────────────┤ │ `<CR>` │ presionar *ENTER* │ └────────────────────────┴───────────────────────────────────────────────────┘
Presionando `F6` se actualiza el tiempo consumido, por lo general es útil cuando pasaron unos minutos de revisión del *diff* o si hubo un tiempo extra de confirmación y/o validación de modo externo.
La secuencia de acciones es la siguiente:
┌───────────────────────┬──────────────────────────────────────────────────┐ │ *command* │ *action* │ ╞═══════════════════════╪══════════════════════════════════════════════════╡ │ `:2` │ ir a la línea 2 │ ├───────────────────────┼──────────────────────────────────────────────────┤ │ `<CR>` │ presionar *ENTER* │ ├───────────────────────┼──────────────────────────────────────────────────┤ │ `:r!git-last-timemsg` │ ejecutar `git-last-timemsg` y escribir contenido │ ├───────────────────────┼──────────────────────────────────────────────────┤ │ `<CR>` │ presionar *ENTER* │ └───────────────────────┴──────────────────────────────────────────────────┘
En resumen, la secuencia habitual puede ser presionar `F3` y `F4`, ajustar el *Subject* y listo, sale el *commit*, otras veces puede ser primero `F3` y `F4`, luego `F5` y finalmente `F4` o también se puede prescindir de `git-commit-message` y simplemente presionar `F6` para agregar/actualizar el tiempo consumido y editar el *Subject* sin condicionamientos.
Es una especificación para dar significado a los mensajes de los *commits* haciéndolos legibles para máquinas y humanos. Si bien todavía no lo estoy usando fielmente, es una fuente de inspiración y una buena estrategia a futuro utilizarla.
`2022-11-21 23:10`[9] agregar "cómo escribir rápidamente mensajes de commit de git usando vim"
-- Response ended
-- Page fetched on Fri May 17 06:57:27 2024