Archive

1046 posts · Page 1 of 88. ← Blog

Pratik Dhanave · ·6 min read

Rewriting History Safely

Git lets you rewrite history — amend a commit, squash a messy branch, drop a secret that was committed by mistake. But "rewrite" is a misnomer: you never edit a commit, you replace it with a new one and move a pointer. Once you understand that, the rules for doing it safely become obvious, and the one genuine danger — rewriting history other people are building on — comes into sharp focus. This closing post turns the whole series into a working discipline.

"Rewrite" is a misnomer: you never edit a commit, you replace it with a new one and move a pointer. Once you see that, the rules for doing it safely become obvious — and the one real danger, rewriting history others build on, comes into sharp focus. The capstone that turns the series into a discipline.

Pratik Dhanave · ·5 min read

Remotes, Refspecs, and How Fetch and Push Work

Collaboration in Git is the same object model, stretched across two repositories. A remote is just a named URL; a remote-tracking branch is just a local pointer that remembers where the other side was; fetch and push are just object transfers plus ref updates, governed by a small syntax called the refspec. Nothing new is invented for the network — it's the graph and the pointers, reaching across a wire.

Collaboration in Git is the same object model stretched across two repositories. A remote is a named URL; a remote-tracking branch is a pointer remembering where the other side was; fetch and push are object transfers plus ref updates governed by refspecs. The network adds almost no new concepts.

Pratik Dhanave · ·5 min read

The Reflog: Git's Safety Net

"I lost my commits" is almost never true. A bad reset, a botched rebase, a deleted branch — the commits are usually still there, sitting unreachable in the object store, waiting out their grace period before garbage collection. The reflog is the log of everywhere your refs have been, and it's the tool that turns "I destroyed my work" into a thirty-second recovery. Knowing it exists changes how fearlessly you can use Git.

"I lost my commits" is almost never true. A bad reset or botched rebase leaves the commits sitting unreachable in the object store, waiting out a grace period. The reflog is the log of everywhere your refs have been — the tool that turns "I destroyed my work" into a thirty-second recovery.

Pratik Dhanave · ·7 min read

Measuring Go-to-Market

Without measurement, GTM is guessing — you can't tell a channel that works from one that flatters you, a healthy business from one quietly bleeding, or whether your last change helped. But GTM measurement has a trap engineers fall into from the opposite side: drowning in dashboards of vanity metrics that feel rigorous while missing the two or three numbers that actually decide whether the business works. This closing post is about measuring what matters — and the unit economics that separate a real business from an expensive way to lose money.

Without measurement, GTM is guessing — but the engineer's trap is drowning in dashboards of vanity metrics that feel rigorous while missing the two or three numbers that actually decide whether the business works. This is about measuring what matters — and the unit economics that separate a real business from an expensive way to lose money.

Pratik Dhanave · ·8 min read

System Calls, and Why OS Knowledge Matters

You can build software for years treating the operating system as a black box — and then one day a production mystery (a service that's slow for no reason, a memory crash, a concurrency heisenbug, a server that won't scale) has an answer that lives entirely below your framework. OS knowledge is what lets you see down there. This closing post shows how everything in the series connects, through the system-call boundary and the diagnostic power it gives you.

You can build software for years treating the OS as a black box — then a production mystery has an answer that lives entirely below your framework. OS knowledge is what lets you see down there. How everything connects, through the system-call boundary and the diagnostic power it gives.

Pratik Dhanave · ·5 min read

Packfiles and How Git Stays Small

A snapshot-per-commit model sounds like it should balloon a repository to enormous size. It doesn't — a project with a decade of history often clones smaller than a single day's build artifacts. The trick is packfiles: Git periodically takes its loose objects, deltas the similar ones against each other, and compresses the result. This is where "Git stores snapshots" and "Git repositories are tiny" stop seeming contradictory.

A snapshot-per-commit model sounds like it should balloon a repository, yet a decade of history often clones smaller than a day's build artifacts. Packfiles are the trick: Git deltas similar objects against each other and compresses the result — a storage layer under the snapshot model, invisible in daily use.

Pratik Dhanave · ·7 min read

Launch and Adoption

A launch feels like a finish line — the day you finally ship to the world — but it's actually a starting line, and the most dangerous myth in go-to-market is that a big launch equals success. Most durable companies weren't made by a viral launch day; they were made by the unglamorous work of getting a few early customers to genuinely succeed, then carefully expanding from there. Adoption is a curve you climb, not a switch you flip, and the hardest part of that curve is the gap that kills more products than any competitor.

A launch feels like a finish line, but it's actually a starting line — and the most dangerous myth in go-to-market is that a big launch equals success. Adoption is a curve you climb, not a switch you flip, and the hardest part of that curve is the chasm that kills more products than any competitor.

Pratik Dhanave · ·8 min read

I/O and the I/O Models

The difference between a server that handles a hundred connections and one that handles a hundred thousand on the same hardware usually comes down to one choice: how it does I/O. Blocking, non-blocking, and asynchronous I/O aren't interchangeable styles — they're fundamentally different models with different scaling limits, and understanding them explains async/await, event loops, and why the network stack works the way it does.

The difference between a server handling a hundred connections and one handling a hundred thousand usually comes down to one choice: how it does I/O. Blocking, non-blocking, and asynchronous I/O are fundamentally different models with different scaling limits.

Pratik Dhanave · ·7 min read

Operators and Kubernetes in Production

Kubernetes's deepest idea isn't its built-in objects — it's that the reconciliation model is extensible. You can teach Kubernetes new concepts and automate operating them, which is what operators do. This closing post covers that extension model, the realities of running Kubernetes in production, and the honest verdict on when its power is worth its complexity.

Kubernetes's deepest idea isn't its built-in objects — it's that the reconciliation model is extensible. You can teach Kubernetes new concepts and automate operating them, which is what operators do. Plus the realities of running it in production, and when it's worth the complexity.

Pratik Dhanave · ·7 min read

Building and Adopting a Platform

The hardest part of platform engineering isn't the technology — it's building a platform people actually adopt, and knowing whether it's working. This closing post covers treating the platform as a product, measuring it with DORA metrics and adoption, structuring the team, and the failure modes that sink platforms. Getting these right is what turns platform engineering from a project into a lasting capability.

The hardest part of platform engineering isn't the technology — it's building a platform people actually adopt, and knowing whether it's working. Treat the platform as a product, measure it with DORA metrics and adoption, and avoid the failure modes that sink platforms.

Pratik Dhanave · ·7 min read

Modules, Crates, and Project Structure

As a program grows past one file, you need a way to organize it — to group related code, control what's public, and pull in libraries. Rust's module system does this with a clear hierarchy and privacy-by-default, and understanding crates, modules, and paths is what lets your projects scale beyond a single main.rs. This closes Module 2.

As a program grows past one file, you need a way to organize it — to group related code, control what's public, and pull in libraries. Rust's module system does this with a clear hierarchy and privacy-by-default.

Pratik Dhanave · ·6 min read

Merge and Rebase, Demystified

Merge and rebase are where Git's DAG earns its keep — and where most fear lives. Both integrate one line of work into another; they differ only in the shape of history they leave behind. Merge preserves the fork and records a convergence; rebase rewrites your commits as if you'd started later, producing a straight line. Neither is magic. Once you know what a merge base is, both become predictable.

Merge and rebase both integrate one line of work into another; they differ only in the shape of history they leave. Merge preserves the fork and records a convergence; rebase replays your commits as new objects into a straight line. Once you know what a merge base is, both become predictable.