Tutorial
Link commits to cards automatically
Install a post-commit hook that attaches every commit to the right card — and learn why the position of the key in the commit decides whether the card moves.
Last updated:
Anyone who writes a card key into a commit has already documented the work — it is just in the wrong place. This guide installs a post-commit hook that attaches every commit to the right card automatically, with author, SHA, branch and message. Git integration is included in the Developer plan.
What you need
- The Developer plan — it carries git integration and API access. See pricing.
gitandcurllocally.- A repository — GitHub, GitLab, Gitea or self-hosted, it makes no difference.
1. Check your plan and tools
The hook talks to the Zuuna API. Both git integration and API access belong to the Developer plan; on lower plans the endpoint does not answer.
2. Create an API token
Open the developer console in Zuuna and create a token. Give it only the scope the hook actually needs: git:write. The token starts with zk_live_ and is shown exactly once — after that only its prefix is visible.
3. Install the CLI
In the root of your repository:
curl -o zuuna https://app.zuuna.de/zuuna.sh && chmod +x zuuna
4. Connect the repository
./zuuna init https://app.zuuna.de zk_live_your_token [group-id]
This writes .git/zuuna.conf and installs a post-commit hook. From now on every commit sends two events to Zuuna: the commit itself and the branch it was made on. Both live in .git/ and therefore outside the repository — your token is never committed.
5. Write your first commit with a card key
Here is the part almost no tool explains: where the card key sits decides what happens.
| Where the key appears | Meaning | Effect |
|---|---|---|
| Subject line, or branch name | work | links and fires automations |
Body, after fix, fixes, closes, resolves, implements | work | links and fires |
Body, after ref, see, part of, related to, via | reference | links only — no automation |
| Body prose, no keyword | — | nothing at all |
The distinction exists for a concrete reason: a commit carrying "logged as ZNA-248 for later" in its body once dragged four untouched backlog cards onto "Git committed". The board claimed work that never happened. If the same key appears in both positions, work beats reference.
So a clean commit looks like this:
ZNA-164: add sprint picker to the backlog
Preselects the active sprint.
ref ZNA-165
ZNA-164 counts as work and moves the card; ZNA-165 is merely linked.
6. Check the result on the card
Open the card. The development section now lists the commit, the author, the SHA and the branch. "What actually belongs to this ticket?" stops being a search through the git log and becomes a line on the card.
Troubleshooting
- Nothing happens. Check the hook first:
.git/hooks/post-commitmust exist and be executable. A clone of the repository does not bring it along. - The commit is linked but the card does not move. Then the key sat in the body without a keyword, or behind a reference keyword. See the table above — that is deliberate, not a bug.
- Wrong prefix. The key must match the group's card prefix and is matched uppercased.
- 401 or 403 in the hook output. The token expired, was revoked, or lacks
git:write. Create a new one and runzuuna initagain.
Next steps
- Connect GitHub pull requests to your board — the step after commits.
- Move cards automatically with git — turn events into rules.
- Git on the board and project management for developers.
FAQ
Does this work with GitLab, Gitea or self-hosted git?
Yes. The hook is a plain HTTPS call made from your local repository — it does not care where the repository is hosted. Pull requests are the exception: PR tracking runs through GitHub only today.
Do I have to install something in every repository?
Yes. The hook lives in that repository's .git/hooks and does not travel with a clone. One zuuna init per repository and you are done.
Can I name several cards in one commit?
Yes. List them individually (ZNA-164 ZNA-165) or use the slash shorthand: ZNA-164/165/166 repeats the prefix for you.
What happens on a rebase or force-push?
The hook runs on commit, not on push. Rewritten commits get new SHAs; the old links stay on the card. That is deliberate — the card shows what actually happened, not the tidied-up version.
Which plan do I need?
The Developer plan. It carries the git integration and the API access the hook uses.