Back to the blog
Reporting engineering·April 18, 2026·6 min read

GitHub vs Jira for client reports: why commit history wins

Jira tickets describe what you planned. GitHub commits describe what you shipped. For client reporting, the difference matters more than most agencies realize.

Ask any software agency how they produce a weekly client report and the answer usually involves a ticket tracker: Jira, Linear, Notion, ClickUp, whatever the team settled on. You export the tickets closed this sprint, group them by epic, and paste the list into a slide or an email. Clean, repeatable, audit-friendly.

And quietly wrong.

Ticket-based reports describe what the team planned to do. Commit-based reports describe what the team actually built. Those two sets overlap heavily most weeks — but they never overlap completely, and the places they diverge are exactly the places a client would want to know about.

The three ways tickets lie

1. Work that happened without a ticket

Every engineering team ships work that was never tracked. A hotfix went out at 2 AM. A dependency upgrade turned into a rabbit hole. A colleague left a feature flag on and the cleanup PR landed Friday afternoon. None of this shows up in Jira because nobody stopped to create a ticket first. All of it shows up in the commit log.

A ticket-based report under-represents the team’s actual output by some fraction — usually somewhere between 10% and 30% based on what we see inside commitplain-analyzed repos. That’s engineering capacity the agency paid its developers for and then failed to bill the client’s attention for.

2. Tickets that closed without shipping

The inverse is worse. A ticket moves to “Done” because the developer opened a PR, because QA signed off, because the team decided to postpone the last 20%, or because the backlog groomer needed to clear the board. None of these states match the only question the client actually cares about: did the change land in production?

Commits are a tighter truth-proxy for shipped work than any ticket status. If code reached `main` and a deploy happened, it’s in the product. If it didn’t, it isn’t — regardless of what the ticket says.

3. Tickets that describe something other than what was built

Scope drift is the normal state of any non-trivial ticket. The engineer starts implementing “add a bulk-delete button,” discovers the underlying model can’t cascade deletes safely, and ends up rewriting the soft-delete logic. The ticket still says “add a bulk-delete button.” The commit messages describe the real work: `fix(model): cascade delete ordering`, `refactor(user): soft-delete via tombstone`, `feat(admin): bulk delete UI`.

A report drawn from tickets reads “added bulk-delete button.” A report drawn from commits can say what actually happened: “Rewrote the deletion pipeline to support cascading, then added the bulk-delete UI on top. The rewrite is the reason this took longer than estimated; it also unblocks the upcoming GDPR data-export feature.” The second version is more honest, more informative, and — crucially — buys the team credit for the deeper work.

Where tickets still matter

None of this is an argument against ticket trackers. Jira is a useful planning tool. Linear is a useful execution tool. Both are essential for prioritization, dependency tracking, and assigning ownership across a team. What they are not good at is faithfully describing the work that got shipped.

A practical split:

  • Tickets for planning and forward motion. They describe intent, estimate effort, and track who is doing what.
  • Commits for reporting and rearview motion. They describe reality: what landed, when, by whom, affecting what code.

Agencies that use tickets for both tend to over-report ceremony and under-report substance.

The objection: commits are too granular

The standard pushback is that commits are too noisy for a client. “Fix typo in button label” is not a status report entry. That’s true, and that’s also a solved problem: commit-based reporting needs a layer of summarization on top of the raw log. Filter by conventional commit type (`feat`, `fix`, `refactor`, `perf`) to drop the noise. Group by repo area or branch prefix. Translate into executive language.

This is exactly what commitplaindoes: it reads your real commit history — including on the Agency plan the actual diffs of the commits you select — and produces a summary in the tone and language your client needs. Not “fix(auth): tighten session timeout,” but “Shortened session expiry on the admin panel to reduce the risk of leaked tokens being reused.” One is for developers. The other is for the person paying the invoice.

The test

Next time you write a weekly report from tickets, do a parallel draft from the commit log. Compare. Every difference is a signal: something shipped that wasn’t tracked, something tracked that didn’t ship, or something that changed scope on the way. The gaps are where the most interesting conversation with the client happens.

From the team that writes this blog

Stop writing client reports from scratch.

commitplain reads your real GitHub commits and drafts an executive client report in your tone — reviewed and approved by you before anything reaches your client.

See how it works