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.
  • git and curl locally.
  • 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 appearsMeaningEffect
Subject line, or branch nameworklinks and fires automations
Body, after fix, fixes, closes, resolves, implementsworklinks and fires
Body, after ref, see, part of, related to, viareferencelinks only — no automation
Body prose, no keywordnothing 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-commit must 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 run zuuna init again.

Next steps

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.

Rebuild this step in your own workspace.

The guide takes a few minutes — it sticks when it is your own board underneath. 14 days of full access, no credit card.