lazycommit:用本地模型生成 Git 提交訊息的 CLI 工具
lazycommit: a tiny local model writes my commit messages so I don't have to
作者開發了 lazycommit,一款以本地小型模型讀取已暫存的 Git diff 並生成 Conventional Commit 訊息的 CLI 工具。工具以純 Python 編寫、沒有依賴,預設使用約 400 MB 的 Qwen2.5-Coder 0.5B Instruct,原始碼在 https://github.com/MRNOWSHIRWAN/lazycommit。
Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥
This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 3.
What I Built
lazycommit is a small CLI that writes git commit messages for me. I stage my changes, run lazycommit, and a small open-weight model running on a server VM reads the diff and answers with one Conventional Commit message, like feat: add timeout option to portscan. With lazycommit --commit it commits right away.
I commit to GitHub every day. Writing the message is the part I always want to skip, and "fix stuff" as a message helps nobody. This is the laziest useful thing I could build: one command, and the boring part is done.
The whole tool is plain Python with zero dependencies. It talks to any local server that speaks the OpenAI chat API: Ollama, llama.cpp, LM Studio. The default model is Qwen2.5-Coder 0.5B Instruct, about 400 MB, which runs fine on a laptop CPU.
Demo
Here is a real run in a demo repository. I staged a change that adds a timeout option to a small port scanner:
$ lazycommit
lazycommit: 1 staged file(s): portscan.py
lazycommit: asking qwen2.5-coder:0.5b-instruct at http://127.0.0.1:18090/v1 ...
feat: add timeout option to portscan
Then two more real commits, fully written by the model:
$ git log --oneline
106f562 test: add test for localhost closed port
4595f1b docs: add README with project description
b8f5cf6 feat: add timeout option to portscan
0010f18 feat: basic tcp connect scanner
The model picked the right Conventional Commit type all three times: feat for the feature, docs for the README, test for the test file. Each message took about 2 seconds on a 2-core VM with the model on CPU. That is one measured result on that VM, not a benchmark.
Code
Source code on GitHub: https://github.com/MRNOWSHIRWAN/lazycommit
The application code is MIT licensed. The model weights keep their own Apache-2.0 license.
Setup takes two commands if you have Ollama:
pip install git+https://github.com/MRNOWSHIRWAN/lazycommit.git
ollama pull qwen2.5-coder:0.5b-instruct
Then lazycommit inside any git repo with staged changes.
How I Built It
The pipeline is small on purpose:
- Read
git diff --cached, staged changes only. - Trim very large diffs so a small model stays inside its context window, keeping every changed file's name visible.
- Ask for one message with three tiny examples (a feat, a docs, a test diff). I found that a 0.5B model follows one concrete example much better than a paragraph of instructions. Without the docs example it called a README change a feat; with it, it gets the type right.
- Clean the output: strip quotes, markdown fences, and "Commit message:" lead-ins, lowercase the summary. If nothing usable remains, it says so and asks you to write the message yourself. It never invents one.
The default mode only prints the suggestion. --commit is a separate, deliberate flag. There are 15 pytest tests covering the cleanup rules, the diff trimming, the HTTP client against a fake local server, and the full flow in a temporary git repository. All pass.
Why Open Innovation Matters
A commit message generator that sends your diff to a hosted API is a strange product. Your staged diff is exactly the code you have not published yet. With an open-weight model, the diff never leaves the machine: no account, no API key, no terms of service, no per-request cost. It works offline, on a train, and it will still work in five years because the weights sit on my disk.
Open weights also made the engineering honest. I could read the model card, check the license, download the exact file, and run it with an open-source server (llama.cpp). If a bigger model writes better messages tomorrow, I change one environment variable and keep everything else.
The tradeoff is real and I want to name it: a 0.5B model is not a genius. It gets the type and the subject right far more often than not, but I still read the message before I push. That is why the default mode only prints. Being lazy is the goal; being careless is not.
For me this was also a first real step from using AI through chat windows to running AI as a local component in my own tool, and that shift only happened because the model and the server are open.
來源:DEV Community · dev.to