Blog · · 4 min read
Turning Git commits into client updates people understand
Commits are written for developers, not clients. A translation method — with a real before/after — for turning Git activity into updates clients trust.
Commit messages and client updates fail at each other's jobs for a simple reason: they're written for different readers. A commit message tells a future developer what changed in the code; a client update tells a non-technical person what changed in their world. The translation between them is a skill — mechanical enough to systematize, and worth systematizing because your Git history is the most honest record of your week that exists.
TL;DR
Don't paste commits; translate them. Group a week's commits by feature or outcome, name each group by its user-visible result ("password reset works on mobile now"), explain invisible work by its purpose, and flag anything the client should act on. One outcome = one bullet, regardless of commit count. The before/after below shows the whole move.
Why can't clients just read the commit log?
Look at a real Tuesday:
fix: null check on session refresh (again)refactor: extract PaymentIntent builderwip checkoutfix Safari focus trap in modalbump stripe sdk, pin zodrevert "wip checkout"
To you, a normal day. To a client: alarming noise. "Again"? A revert? "wip"? They can't tell progress from churn — and worse, the log's volume doesn't map to value. The day you fix a catastrophic one-line bug produces less Git activity than the day you rename files. Clients reading raw logs learn to count commits, and counting commits is how you end up defending your busiest-looking day instead of your most valuable one.
What does a good translation look like?
Here's that same week, translated. Before — the raw log (six commits above, plus twenty more like them). After — the client update:
Done this week
- Checkout is stable on Safari — fixed the bug that dropped some iPhone users at the payment step, and a related session issue behind it.
- Payments groundwork — restructured the payment code and updated our Stripe integration, so next month's subscription features build on solid footing.
- Started the new checkout flow — first pass in progress; on track to demo Friday.
Needs your attention: nothing this week.
Twenty-six commits, three bullets. Notice what the translation did: grouped by outcome, named the user-facing result first, gave the invisible refactor a purpose, and honestly labeled in-progress work as in-progress (the revert disappeared — reverting your own WIP isn't news, it's process).
What's the method, step by step?
- Group the week's commits by outcome. Not by day, not by repo — by "what is true now that wasn't before." Most weeks collapse into three to six groups.
- Name each group by its user-visible result. Test: would the client's co-founder understand the bullet without you in the room? "Search filters are live" passes; "implemented faceted query builder" doesn't.
- Translate invisible work by purpose. Refactors, upgrades, and test coverage all have a why the client cares about — speed, safety, or cheaper future features. Say the why. (Never invent one; if the honest why is "the code was bothering me," fold it into a related outcome or leave it out.)
- Separate done / in-progress / needs-input. In-progress work labeled honestly builds trust; in-progress work presented as done destroys it retroactively.
- Cut the rest. Dependency bumps, CI fiddling, fix-the-fix chains — gone, unless one of them is the story ("patched the OpenSSL vulnerability same-day").
Drop the result into a consistent shape — the weekly-standard skeleton from the status report templates fits exactly — and send it the same day every week, before anyone has to ask. (If they're already asking, start with what "any updates?" really means.)
Can the translation write itself?
The mechanical 80%, yes. This is exactly what WorkedOn was built for on the freelancers & agencies side: it connects to GitHub or GitLab read-only, reads the week's commits and merged PRs — including diff context, so a lazy message like "fix" still produces a meaningful summary — groups them by outcome, and drafts the plain-English update in your tone. The 20% that stays human is judgment: you review, reorder, delete a line, add the context only you know, and approve before anything reaches the client. Your commit hygiene stops mattering to your client communication, which frees commit messages to do their actual job: talking to future you.
FAQ
Should I show clients my actual commit messages?
Almost never raw. Commit messages are notes to future developers — full of jargon, fix-the-fix chains, and internal references. Translate them into outcomes; link the repo only for clients who ask.
How do I explain refactoring or invisible work to a client?
Name the user-facing consequence: "Rebuilt the checkout code so the two features you asked for next month ship faster and with fewer bugs." Invisible work has visible purposes — report the purpose.
How many commits equal one update bullet?
As many as share an outcome. Twelve commits that ship search-filtering are one bullet: "Search filters are live." The client counts outcomes, not commits — bullet count should track value, not activity.
Can this translation be automated?
The mechanical parts, yes — grouping commits by feature, reading diffs for context, drafting plain-English summaries. The judgment (what to emphasize, what to flag) should stay yours: automate the draft, review before sending.