Saltar al contenido principal

% 16k.es

Usando inteligencia artificial para crear mensajes de commit útiles

Tengo un par de tareas o pequeños proyectos donde una tarea en segundo plano se encarga de hacer commit a git y pushear a github.

Ni que decir que tiene que el 99% de todos los commits de mi vida solían ser del tipo “corregir error”, “actualizar readme” o “añadir punto y coma que falta”. Con los commits automáticos es aún peor: ahora todo es “commit automático desde el portátil de casa”. Meh.

Gemini AI logo

La mayoría de las veces no es tan importante es el mensaje de commit, pero a veces sí lo es. Al fin y al cabo, por eso git commit lo requiere.

Me gustaría poder echar un vistazo rápido al diff y resumirlo en un mensaje muy corto para pasarlo al script de commit. Por supuesto, la automatización ya no sería automática. ¡Qué deastre!

Pero u momento… ¿leer un texto corto y resumirlo no es exactamente lo que la IA puede hacer? ¿Por qué no intentarlo? ¿Podría un simple script mirar los cambios y generar un mensaje de commit decente?

# ¿Qué modelo usar?

sólo Pregunta fácil. Dado que OpenAI ya no ofrece un nivel 100% gratuito, elegí la API Gemini ya que actualmente es gratis. Sí, lo sé 👹 Puede que lo intente más adelante con un modelo local, pero no hoy.

El código para conseguirlo es realmente trivial. Por cierto, al principio quería usar Go, pero el Debian que estoy usando tiene instalado go-1.19 y se necesita al menos la 1.21, así que he utilizado Python en su lugar.

Todo lo necesario es el paquete google-generativeai:

python3 -m venv ai-commit
cd ai-commit
source bin/activate
python3 -m pip install --upgrade google-generativeai

La idea general es que el proceso en segundo plano escriba el diff en un archivo y luego llame al script python. Éste lee el diff, genera un mensaje de commit y lo devuelve al proceso en segundo plano, que lo utilizará para hacer el commit en git.

Un simple fichero ini se utiliza para almacenar la clave de la API y el modelo a utilizar.

Estos son los pasos básicos:

# import the Gemini stuff
import google.generativeai as genai

# read config, parse arguments and that stuff...
# [...]

# setup model
model = genai.GenerativeModel(generative_model)
genai.configure(api_key = api_key)

# create prompt
prompt = "create a short commit message (less than 80 characters long) from this diff:"

# read diff from file
with open(f, "r") as f:
    diff = f.read()
prompt = prompt + diff
text = generate_commit_msg(prompt)
print("{}".format(text))

…and the function called is just:

def generate_commit_msg(prompt):
    try:
        response = model.generate_content(prompt)
        return(response.text.rstrip('\n'))
    except:
        print("Sorry, I could not get a response")
        raise
        sys.exit(1)

(el código está aquí)

# Ejemplo

Estoy escribiendo el temario para una futura charla en un colegio. Esta es una salida del git diff del guion:

diff --git a/events/daw 2024/daw 2024 topics.md b/events/daw 2024/daw 2024 topics.md
index cea35f6..782c8c1 100644
--- a/events/daw 2024/daw 2024 topics.md
+++ b/events/daw 2024/daw 2024 topics.md
@@ -7,0 +8,3 @@
+- OWASP top 10
+- OWASP top 10 mobile

Nota: para el diff estoy usando:

git diff --minimal --ignore-submodules --no-color --unified=0

La salida se escribe en un fichero y luego se llama al script python pasándole el fichero como argumento:

source /path/.../Projects/ai-commit/bin/activate
/path/.../Projects/ai-commit/ai-commit.py /tmp/foobar.diff

Y el resultado es…

Add OWASP Top 10 topics to DAW 2024 agenda

…que es lo que irá al mensaje de commit:

git log --oneline
2a4cc72 (HEAD -> main, origin/main, origin/HEAD) Add OWASP Top 10 topics to DAW 2024 agenda
03e2617 auto-commit from old laptop
f392d10 auto-commit from old laptop
0352b1a auto-commit from old laptop
a3b2b11 auto-commit from old laptop
93b2a10 auto-commit from old laptop

Mola, ¿verdad? 😄