What did I do this week? One command to answer it

I work on several machines, and some of them aren't mine. At the end of the week I need to know what I did on each one, and the answer was spread across dozens of repositories. didwhat is a command that gets it in one step, with nothing to install but a binary.

Every Friday I ask myself the same question: what did I do this week?

I need the answer for the standup, for the timesheet and for my worklog. And I can almost never answer it from memory. The work is in the commits, but the commits are spread across many repositories, many branches and, above all, several machines.

Some of those machines aren’t mine. One is a client’s laptop: Windows 11 Enterprise, managed by their IT team, where I can’t install Python or Node. Part of my week lives there, and what happens on that laptop stays on that laptop.

What I did before

I used a bash loop that walked the folders and ran git log in each repository. I pasted it into the terminal by hand every time I needed it. It had three problems:

  • It only ran in Git Bash. PowerShell needed a translation, and a locked-down machine doesn’t always have Git Bash.
  • It mixed up dates. git log --since filters by commit date, not author date. A rebase done today pulled two-week-old work into the report.
  • It lost the mornings. Git reads --since=2026-10-13, with no time, as that day at the current time of day. If I ran it at four in the afternoon, everything before four was gone. I found out weeks later.

A script you paste by hand and that fails silently isn’t a tool. So I turned it into one.

didwhat

didwhat is a command that lists your commits from every repository under a folder, grouped by day:

didwhat --since 2026-10-13 ~/code/client
## 2026-10-14

### platform

- 10:12 `57a5e82` feat: record when an invoice enters and leaves scope — *past-due-history*
  - etl/scope.py
  - web/src/InvoiceHistory.tsx

## Not pushed or not committed

### web — `main...origin/main [ahead 1]`

- `M` src/worklist.tsx

It finds the repositories by itself, looks at every branch, remote and tag, and at the end says what is still uncommitted or unpushed. The output is Markdown, ready to paste into a standup or a worklog. With --json it is JSON, to process with jq.

Why Rust

I didn’t pick Rust for its own sake. The constraint was the client’s laptop: it had to run on a machine where I can’t install a runtime.

Rust compiles to a single binary with no dependencies. The Windows one is under 500 KB zipped, and all it needs is git on the PATH, which is already on any machine where people write code. Every GitHub release ships binaries for Windows, macOS and Linux, with one-line installers. And if that machine doesn’t allow running an install script either, you download the .zip, unzip it and you’re done.

What real repositories taught me

The tests passed from day one. The problems showed up when I ran it against twenty real repositories, and each one became a rule of the tool.

A commit counts on the day you wrote it. A rebase changes the commit date but not the author date. didwhat uses the author date, so reorganizing a branch today doesn’t bring its old work into today’s report. And a commit made at 23:30 shows up on that day in local time, not on the UTC day.

Each change is listed once. This was the hardest one. When a pull request is squashed or cherry-picked, the main branch gets another commit with the same changes, a different hash and a different date. The report showed everything twice. didwhat compares the changes with git patch-id, which identifies a diff whatever its message says, and lists the change once, on the day you made it, with where and when it landed:

- 13:18 `94df89d` docs: document the tour conventions — *feat/onboarding-tours* → landed as `fa5be5b` at 13:38, a squash of 7 commits

That also works for a branch of several commits squashed into one: it looks for the run of your commits whose changes add up to exactly those of the squash.

A date with no time is the whole day. --since yesterday --until yesterday covers midnight to midnight, instead of being an empty instant.

A date git doesn’t understand is an error. Git reads monday as “now”, without a warning, and the report comes out empty. You’d think you did nothing on Monday. didwhat stops and suggests last monday.

Other people’s merges aren’t your work. In a busy repository there were twenty a day, and they buried everything else. Now they only show up with --merges.

What I get from it

  • One command instead of an hour. What used to be rebuilding the week from GitHub, Slack and memory is now running didwhat and reading.
  • Nothing to install on someone else’s machine except a binary. No admin rights, no runtime.
  • It stays off the network. By default it only reads what is on disk. With --fetch it pulls the remotes first, and if a repository asks for credentials it reports a warning instead of waiting.
  • It includes what doesn’t exist anywhere else yet. Uncommitted changes and unpushed branches don’t show up on GitHub or in Jira. If I leave something behind on the client’s laptop, it tells me.
  • Numbers I can trust. When each change is listed once and on its own day, I can count commits per day without cleaning them up first.

What it doesn’t do

didwhat only sees git. Meetings, code reviews, decisions, and hours spent on something that never became a commit aren’t there. For that I still keep a worklog, and to read it I built Noonly. didwhat doesn’t replace it; it gives me the starting point to write it.

It doesn’t recognize every squash either. If a pull request is squashed together with someone else’s commits, or changed while resolving a conflict, its changes no longer match any run of yours and it is listed on its own. I’d rather it repeat something than hide it.

Try it

On macOS and Linux:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/neosergio/didwhat/releases/latest/download/didwhat-installer.sh | sh

On Windows, from PowerShell:

powershell -ExecutionPolicy Bypass -c "irm https://github.com/neosergio/didwhat/releases/latest/download/didwhat-installer.ps1 | iex"

Then, in the folder where your repositories live:

didwhat

With no arguments it shows the last seven days. The code is on GitHub, under the MIT license. If something doesn’t work for you, open an issue: the next steps are already there.

Comments