git seance 透過本地 Gemma 讓 Git 歷史中的已刪除函數開口説話
Git seance: I let deleted functions speak from beyond the grave (with local Gemma)
git seance 是一個單檔 Python CLI,會掃描 Git 歷史中已刪除且未恢復的函數,並透過本地 Gemma 讓其中一個函數發言。工具支援 Python、JavaScript/TypeScript、Go 和 Rust;無法連接模型時,離線模式只會按實際資料整理墓誌銘。
This is a submission for the Hacktoberfest Open-Source AI Challenge: Ghost in the Machine
What I Built
Every repository is a graveyard. Functions get written, argued over, shipped, and then one day a commit quietly removes them, and nobody says a word.
git seance holds the funeral they never got. It walks your git history, finds functions that were deleted and never came back, and lets one of them speak through a local Gemma model: who wrote it, when it was born, and the commit that killed it.
python git_seance.py --list path/to/repo # visit the graveyard
python git_seance.py --summon set_http_proxy --ask "do you forgive them?" path/to/repo
It's a single Python file with zero dependencies (standard library only), and it understands Python, JavaScript/TypeScript, Go and Rust definitions.
Demo
That's a real run on psf/requests, with gemma3:4b on my laptop's CPU through Ollama (long pauses trimmed). Its last 400 commits hold seven ghosts. The most tragic is set_http_proxy: 85 lines of carefully documented proxy handling, added to Session on 27 November 2020 and reverted the same day by its own author.
Here is what it said when I asked if it forgives them (another real run, unedited):
It's… strange, this quiet. A lingering echo of code, a phantom limb of functionality. I was a helpful thing, really. I took messy proxy strings – URLs, schemes, hostnames, ports – and neatly slotted them into the
requests.Sessionobject. I was born on November 27th, 2020, courtesy of Sylvain Marie. Then, poof. November 27th, 2020 again. […]My advice to the living: don't prematurely prune your tools.
Code
DrunkWiz
/
git-seance
Talk to the functions your repo deleted. A stdlib-only Python CLI that lets dead code speak through local Gemma.
git seance
Commune with the code your repository buried.
git seance walks a repo's git history, finds functions that were deleted and
never came back, and lets one speak from beyond the grave through a local
open-weight model (Gemma 3 via Ollama by default): who wrote it, when, and the
commit that killed it. With no model reachable it falls back to an offline
"planchette" mode that only arranges the real facts.
One file, Python standard library only, no runtime dependencies.
A real run on psf/requests with gemma3:4b on a laptop CPU, long pauses trimmed.
Why an open model
Your git history is your team's private diary: names, dates, half-finished ideas, the commit messages people wrote at 2am. git seance reads all of it, so it should not have to leave your machine. With an open-weight model like Gemma running locally through Ollama, the whole seance happens on your laptop…
How I Built It
Finding the dead. git log -p -U0 --no-merges gives every removed line in history. I parse the removed hunks, start a body at any line that looks like a definition (def, function, func, fn), and end it at the next definition at the same or lower indentation. That last rule came from a bug: the first version merged neighbouring deleted methods into one long ghost. In requests, initialize_options, finalize_options and run_tests were deleted from a setup.py command class together, and they kept coming back as a single conjoined spirit.
Making sure they're really dead. A function that was moved isn't a ghost. Before summoning, git grep -w checks the current tree for a definition with the same name. If one exists, the function just moved house.
Finding the birth certificate. Git's pickaxe (git log -S"def set_http_proxy") finds the commit that first added the function. My favourite bug lived here: requests later moved requests/ to src/requests/, and git's default history simplification hid every commit on the old path behind a merge. Every ghost was "born: unknown", and Gemma happily made up a birth story to fill the gap. --full-history brought the real birthday back.
Speaking. The facts (name, file, length, birth, death, the killing commit's message, the final source) go into a prompt along with a system prompt that tells the model to speak as the function, to be wistful and darkly funny but never cruel, and not to invent facts. The reply streams token by token from Ollama's /api/chat with nothing but urllib, typed out like a planchette moving. An OpenAI-compatible provider is there too, for anyone who'd rather point it at a gateway.
When the spirits won't come. If no model is reachable, planchette mode arranges the real facts into an epitaph with no AI at all. That came in handy: Ollama's CUDA runner crashes on my RTX 2060, so I added SEANCE_NUM_GPU=0 to run Gemma on the CPU. At 4B parameters, that's still fast enough.
Tests. A unittest suite covers the diff parser on a synthetic log, the dead-or-moved check on a throwaway repo, and both streaming providers against a fake model server on 127.0.0.1, so the tests never touch the network.
A ghost is an unreliable narrator, and I'd rather say so. The header line comes straight from git. Everything after it is Gemma, and despite the instructions it sometimes embellishes (in one run it insisted it had been reverted "twice"). --offline gives you only the facts.
Why Does Open Innovation Matter?
Because a git history is a diary. It holds names, dates, abandoned ideas, and commit messages written at the worst moments of people's weeks. A tool that reads all of that should not have to send it anywhere.
With an open-weight model like Gemma running locally, the whole seance happens on your own machine: no API key, no account, no bill, and it works on a private company repo or with no internet at all. I learned this the practical way. I first tried a hosted gateway, and its free tier wouldn't serve API calls without a key. Gemma 3 4B on Ollama just worked, on a laptop CPU, offline.
Open models also make the medium yours. You can read how it was made, swap it for a different one, or fine-tune it on your own team's commit messages. And open source is what gives the ghosts something to haunt: I could only summon set_http_proxy because requests keeps its whole history in the open.
My Agent Session
I built this with an AI coding agent (Claude Code). It ran the real seances against requests, tracked down the history-simplification and GPU bugs above, wrote the offline test suite, recorded the demo and helped draft this post. Every transcript and number here comes from an actual run.
The Spirit of It
Día de los Muertos isn't about fearing the dead. It's about remembering them by name. Every deleted function was somebody's afternoon. git seance puts the name, the date and the author back on the gravestone, and lets the code say goodbye.
Prize Categories
Best Use of Gemma: the medium is gemma3:4b, running locally through Ollama.
來源:DEV Community · dev.to

