Can Claude Code Reconstruct a Project History You Never Documented?

Your project’s entire history is sitting in your git log right now. Every decision, every reversal, every “oh, that’s why we do it this way” is in there, timestamped and signed. And you are never going to read it.
I know this because I built a project that grew past my ability to remember how it got that way, and the answer to “how did we get here?” was technically sitting in a few hundred git diffs…..technically. Almost the way a phone number is technically in the phone book. So I pointed Claude Code at those diffs and had it reconstruct the changelog I should have been keeping from day one. It worked, it took about twenty minutes, and the interesting part is not that the AI did it. The interesting part is what made it work, and the thinking that kept it from costing a fortune.
Here is the short version, because you have things to do: yes, Claude Code can rebuild a project’s history from its git diffs into a human-readable changelog. The catch is that it only works well if you scope the job hard, and scoping it hard is the same discipline that keeps the token bill sane. Those two things are the same move. That is the whole post……
Wondering how Claude Code can help SysAdmins in the first place? Episode 046 of SysAdmin Weekly makes the honest case for it, skepticism and all. Give it a watch, then come back for the boring-job version below.
How a one-job tool turned into a system I couldn’t fully trace
I did not set out to build a system. I set out to solve one annoyance.
I host a weekly podcast and newsletter, SysAdmin Weekly, and the one thing I wanted help with was outline generation: real episode outlines with actual linked supporting material, not generic filler. That was it. That was the entire scope. I made a repo, wrote some instructions, and got my outlines.
Then I added episode descriptions. Then social posts ideas for each episode. Then a newsletter research workflow. Then blog post planning and SEO / AEO best practices for this site. Then it turned out each of those needed its own standard operating procedure, so I wrote SOPs. Then the SOPs needed bug-check passes, sanity passes, verification passes, optimization passes, because anything you actually rely on starts accumulating the maintenance work of a thing you actually rely on.
Somewhere in there it stopped being a script and became a system. Multiple workflows, a dozen-plus structural files, processes that referenced other processes. And one day I went looking for when and why a particular rule got added, and I realized I no longer knew. Not “I forgot the details.” I genuinely could not reconstruct the path from where the project started to where it was sitting in front of me.
The information was not lost. It was all right there in the commit history, every change I had ever made, perfectly preserved. It was just locked in a format that a human being will, in practice……..never sit down and ACTUALLY read. ESPECIALLY across a hundred plus different git diffs.
Why your git history is the truth and also useless
Your git history is the most honest record your project has. It is also, for a human, nearly unreadable at scale.
A git diff is the source of truth in the strictest sense: it is the actual change, not someone’s later memory of the change. But “go read three months of diffs across thirteen files and tell me the story” is a task no person volunteers for. The info is real (and it IS there) but the retrieval cost is brutal. That gap, true data that is too expensive in human time to actually go get, is exactly the kind of gap a language model is good for.
So the job was not “summarize my repo.” The job was “translate a record I already trust, from a format I will never read, into one I will.” That framing matters, because it tells you where the AI is allowed to add value (the translation) and where it absolutely is not (inventing history that the diffs do not support). The diffs stay the authority. The model is just the narrator.
That is also why I had started a CHANGELOG file months too late, after the project was already a living tool, and had only been keeping it current going forward. Everything before that first entry was undocumented. This was the backfill.
What I actually asked Claude Code to do
The instruction was narrow on purpose. Four constraints did the heavy lifting.
First, I defined the surface. Not “the whole repo.” The thirteen files that actually shape how the project works: the master instructions file, four workflow SOPs, five templates, the README, the gitignore, and one content-tracking file. Episode transcripts, draft newsletters, and the actual published content were explicitly out of scope. Nobody needs a changelog entry that says “wrote episode 47.”
Second, I told it to leave the existing entries alone. I had already hand-written a couple of recent changelog entries, and I did not want them touched, reworded, or “improved.” Backfill the gap, do not relitigate the parts I already did.
Third, I gave it the output format to match. The existing entries used a dated structure with grouped sections (added, changed, fixed, renamed). The reconstruction had to slot in alongside them and look like it belonged, not like a different author showed up halfway down the page.
Fourth, and this is the one most people skip, I told it how to gather the information without setting tokens and usage limits on fire. More on that next, because it is the actual point.
The result was a clean, dated changelog stretching back to the repo’s first commit on March 30th, each entry written in the same voice and structure as the ones I had done by hand. One excerpt, so you can see the texture:
2026-05-16: Blog post filename convention lowercased
A Hugo behavior catch: Hugo lowercases filenames when generating URL slugs, so title-case source filenames created a mismatch between the repo file and the live URL. Switched convention to lowercase-with-underscores across the board.
That entry is accurate. I know it is accurate, because I lived it. But I could not have told you the date, and I certainly was not going to go dig the commit out by hand to find it.
What does token-conscious AI work look like in practice?
This is the part I actually want you to take away, and the “I use the BEST model for EVERYTHING!!!!” folks annoy the hell out of me. My grandpa firmly instilled “right tool for the right job” into me, so I am going to be specific.
Every token an AI model reads and writes costs something: money if you are paying per token, context budget if you are not, and usually both. Token-conscious work means choosing the path that gets the answer without dragging the model through material it does not need. It is the AI-era version of not running SELECT * against a billion-row table because you only wanted a count.
The naive way to do this changelog job is to have the model read every commit in the repo, in full, and figure it out. That is the SELECT * version. It would have pulled hundreds of content commits, transcripts, newsletter drafts, the works, into the model’s context, the overwhelming majority of which have nothing to do with the project’s structure. Slow, expensive, and noisier, which also makes the output worse. More is not better here. More is just….more.
Again, I focused on three things instead:
- I scoped the read to the thirteen structural files and nothing else.
The history survey only ever looked at diffs touching those paths, so all the episode-and-newsletter noise never entered the picture. Cheaper and more accurate at the same time, which is the usual reward for scoping well.
- I matched the AI model to the sub-task.
The survey work, walking the commits and extracting what changed, is mechanical: high volume, low judgment. The model just has to retrieve stuff in a clear structured repo…not do nuclear physics while rolling a backflip. I ran that particular task on a faster, lighter model. The actual changelog writing, where voice and structure and editorial judgment matter, I kept on the heavier model. No reason to pay top-tier rates to read a diff, and no reason to cut corners on the part a human will actually see.
- Finally I isolated the survey in a subagent.
A subagent is a separate AI worker with its own clean context window that does a defined job and reports back a summary, instead of dumping everything it read into the main conversation. So the grunt work of crawling a few hundred diffs happened off to the side, and only the distilled findings came back to where the writing happened. The main context stayed clean and focused on the part that needed care.
The argument here is that the scoping that saved the tokens is the same scoping that made the output good. Defining the thirteen files was a cost decision and a quality decision in one move. This is almost always true.
Remember:
Vague, expensive prompts and vague, mediocre output tend to be the same prompt.
Can you trust the changelog Claude Code reconstructs?
Not blindly, and the whole premise is what makes that matter.
The entire value of this exercise is accuracy. A changelog that is confidently wrong about your project’s history is worse than no changelog, because now people believe it. So the fact that the diffs are the source of truth is doing real work: the model was translating a trustworthy record, not generating history from “vibes”. That is a much safer job than “tell me what probably happened.”
But “safer” is not “skip the review.” I made the calls that shaped the whole thing:
- what counted as structural
- leaving the existing entries untouched
- which model did which job
- running the survey as a subagent
None of that was the AI deciding on its own. It was a human scoping a tool and the tool executing the scope. And because the premise is accuracy, the output earns a human spot-check against the diffs, not a rubber stamp. If you are going to hold something up as proof your AI got the history right, you should probably confirm it got the history right.
That said, I spot checked a few diffs associated with timestamps from the outputs, and things looked pretty much on the money. As this was a low impact repo without a lot of stakes, I was happy with the output. Had this been a mission critical repo in a high-stakes environment… well… I’d be scrutinizing the output ALOT more than I did in this case.
That is not a knock on the approach. That is the approach. Human sets the boundaries and verifies the result; the model does the retrieval and translation in between. Take the human out of either end and you have a different, worse story.
How to reconstruct your own repo’s history into a changelog
If you have a repo with real history and no changelog, or a changelog you started too late, you can do this today. The shape of it:
- Decide what “structural” means for your repo. For infrastructure-as-code it might be the modules and pipeline definitions, not every variable tweak. For a runbook collection it is the procedures themselves. Write the list down. This list is the whole game.
- Tell the tool to survey only the diffs touching those paths, and to ignore everything else.
- Give it the output format you want, and if you already have entries you like, tell it explicitly not to touch them.
- Have it do the heavy crawling as an isolated job on a cheaper model, and reserve the careful writing for a stronger one.
- Read the result against the diffs before you trust it. The history is the authority, not the summary.
Every ops team I know has a repo like this. Years of decisions buried in a commit log nobody will ever scroll through. The reason it never got documented is not that it was hard. It is that it was tedious enough to never be worth a human’s afternoon. That math just changed.
The boring jobs are worth doing now
The headline most people want to write about this is “look, the AI wrote my changelog.” That is the boring version, and your skeptical-practitioner instinct to roll your eyes at it is correct.
The real story is smaller and more useful. There is a whole category of work that was always valuable and never worth doing, because the payoff did not justify the human hours. Reconstructing institutional memory from a git log lives squarely in that category. So does a lot of the documentation you have been meaning to write and never will. The change is not that machines can suddenly do magic. It is that the cost floor on tedious-but-valuable work dropped far enough that “not worth it” quietly became “worth twenty minutes,” as long as you scope the job and check the result.
If you want the broader version of this argument, with more of the day-to-day ways this shows up in an IT workflow, I made the full case on episode 046 of the SysAdmin Weekly podcast and wrote it up in Can Claude Code Help SysAdmins?. This post is the answer to a narrower question: point it at the boring thing, scope it like you mean it, and watch the bill while you do.
Then go read your own git log. Or better, have something read it for you.