Git Ignore ... and Untrack!

We’ve all done it. You commit a file you shouldn’t have. A .env, a node_modules/ you forgot to ignore, some local config, a stray build folder. So you add it to .gitignore… and git keeps tracking it anyway.

That’s because .gitignore only governs untracked files. Once git is already tracking something, ignoring it does nothing. 🤦‍♂️ The actual fix is two steps:

git rm --cached path/to/file
echo "/path/to/file" >> .gitignore

I do this often enough (and yet I always have to look it up) that I finally built a VS Code extension to do it for me. (Claude helped)

Ignore & Untrack

git-ignore-and-untrack adds a single Ignore & Untrack action to the Source Control context menu. Right-click a file under Changes, pick it, and in one step it:

  1. Removes the file from the git index (git rm --cached), keeping your copy on disk, and
  2. Adds an anchored entry (/path/to/file) to your .gitignore.

Commit to finalize, and the file is gone from version control while your local copy stays exactly where it is.

It’s on the VS Code Marketplace, the source is on GitHub, and it’s licensed 0BSD — do whatever you want with it.

If you’ve ever committed a secret and scrambled to un-commit it, this one’s for you.

**TBF, this won’t fix your history. Rotate those keys!


Software Teams Are the Worst Managed Teams on the Planet

I keep having this conversation. Different companies, different people, different contexts. And I keep landing in the same place.

Software engineering teams are some of the worst managed teams in any industry. Maybe the worst. I’ve seen it across every company I’ve worked at, every company I’ve talked to, and every leadership team I’ve consulted with. It’s pervasive.

And the wild part? It’s not because we don’t know better. The knowledge exists. The frameworks exist. The books have been written. The concepts are not new. I’ve been hearing them for over 20 years. What’s new, somehow, is that experienced managers are still encountering these ideas for the first time.

The Promotion Trap

I think part of this comes down to the youth of software as an industry. We’re still relatively new at this compared to other industries. Software has been able to attract the funding that and reach scales that would’ve taken much more real-world success historically. Therefore, those other industries have had decades (or centuries) to codify what leadership looks like at every level. Software hasn’t. We’re still making it up.

But the bigger issue is the promotion trap.

You were good at writing code, so now you’re managing people who write code. That’s the logic. And it’s terrible logic. These are fundamentally different jobs. Being a great engineer does not make you a great engineering manager any more than being a great pilot makes you a great airline executive. The skills overlap in some places, and an awareness of the work is critical, but the responsibilities are completely different.

I’ve seen this play out so many times. Someone gets promoted because they’re technically strong, maybe they’ve been around a while, maybe they’re just the most senior person on the team. And now they’ve got six or eight direct reports, and they have no idea what to do with them. They’ve never been properly managed before, so why should they? They don’t know how to set expectations. They don’t know how to give feedback. They don’t know how to run a one-on-one that’s actually useful. They definitely don’t know how to have a hard conversation about performance.

So they don’t. They just keep writing code and hope the people stuff works itself out.

It doesn’t. It won’t. Hope is not a strategy.

How Did You Get This Job?

I go to mandatory manager training from time to time. I appreciate it. I’m always grateful for it. Worst case we’ll establish a common vocabulary. But I’ll be honest: most of the content isn’t new to me. That’s fine. What shocks me is watching other managers in the room react to the material like they’ve never heard it before.

How did these people get into a managerial position and not understand the expectations of the role? How did the person who hired them not inspect their skill set in this space? It blows me away. And these aren’t junior people. These are directors, senior managers, people who’ve been in leadership for years.

The concepts aren’t exotic. Have regular one-on-ones. Set clear expectations. Give timely feedback. Create career development plans. Hold people accountable. These are basics. But the bar is apparently so low that “basics” still qualifies as a revelation.

I tend to avoid hiring managers externally who haven’t managed before. I had a situation where a guy was hired as a manager weeks before I started at a company. I met him, went through his background, and asked the obvious question. “Wait, so this is your first time being a manager?” He said yeah. I told him, straight up, I wouldn’t have hired you. Not because you’re not capable, but because you don’t have any of the foundational skills for this particular job.

I gave him two choices. Take the manager role, and I will give you a firehose of mentorship and a massive amount of unsolicited feedback. Or transition back to being a senior IC at the same comp, because you’re clearly excellent at writing code. He chose the management path. And it worked out really well. But it worked because I set those expectations on day one and followed through relentlessly. Most organizations don’t do that. They just hand someone a team and walk away.

The People Paying the Price

Here’s the part that actually bothers me. It’s not the bad managers themselves. People can learn. People can grow. What bothers me is the engineers underneath them who are being underserved and don’t even know it.

Think about how many engineers have never had a manager who gave them real, timely feedback. Never had a manager who built a career plan with them. Never had a manager who set clear, measurable expectations and then actually followed up. These engineers think that’s normal. They think management is supposed to be absent, or reactive, or purely administrative. And they perpetuate that vision when they eventually get promoted into management themselves.

It’s a cycle. Bad management produces people whose only reference for management is bad management. And the engineers at the bottom of that chain just accept that this is how it works.

When I see a group where somebody’s got 18 direct reports, I don’t think “wow, that person is important.” I think that’s 18 people who are not getting served. Nobody can meaningfully manage 18 people. Seven is the sweet spot. Above seven, you start losing the ability to really know what each person is working on, where they’re struggling, and what they need to grow. I managed 14 directs once earlier in my career, and even that was exhausting.

No Consequences, No Change

The other pattern I keep seeing is an almost allergic reaction to accountability in engineering organizations.

I’ve been in conversations where senior leaders have told me, with a straight face, “I don’t think we’ll ever fire an engineer.” Not because every engineer was performing well. Just because the culture was so averse to holding anyone to a standard that letting someone go was unthinkable.

And it’s not just firing. It’s any form of real accountability. I’ve talked with engineering leaders who know that certain people on their teams aren’t embracing new practices, aren’t meeting expectations, aren’t growing. And when I ask what the consequences are for that, the answer is: there aren’t any.

The fear is always the same. They’ve been here for years. They know where the bodies are buried. If we lose them, who’s going to maintain this system? And that fear is real, but it’s also a trap. It means you’re holding onto underperformers because you failed to document the system, failed to cross-train, failed to build any resilience into the team. The institutional knowledge problem is a symptom of the management problem, not a justification for ignoring it.

What I Actually Do

I don’t have some revolutionary framework. What I have is consistency and follow-through. Here’s what I’ve landed on after doing this for a long time.

Managers don’t write application code.

This is probably my most controversial position. I tell every people leader in my organization: you do not contribute to the application code. But you also have to be responsible for and aware of all of the application code being written.

That forces a mindset shift. Your job is not to be the best programmer on the team. Your job is to make the team successful. You participate in code reviews. You understand the architecture. You know what’s being built and why. But your time goes to career development, expectation-setting, coaching, and removing blockers. If you’re heads-down writing features, you’re not doing your actual job.

AI has made me soften slightly on this, because there are cases where a manager prototyping something with an AI tool is genuinely the fastest path. But the principle holds: your primary responsibility is the people, not the code.

Feedback is immediate.

I hate annual performance reviews. Hate them. If I’m doing my job, my team members know exactly where they stand at all times. I have conversations about performance multiple times a week. Not formal sit-downs, just real talk. That went well. This didn’t. Here’s what I noticed in that meeting. Here’s an opportunity you missed.

Feedback should never be delayed. The only exception is if giving it right now would disrupt something that’s actively happening. But immediately after? Definitely. I’m pulling you aside. A lot of the people who still enjoy working with me will tell you that’s one of the things they appreciate most. They always know where they stand.

And here’s the thing: when you do this consistently, the hard conversations become easy. If someone’s performance is slipping and you’ve been talking about it for weeks, the eventual “this needs to change or we’re going to have a bigger problem” conversation isn’t a surprise. It’s a continuation. You talked about this. They knew. The expectations were there. That conversation almost writes itself.

But if you saved it all up for a quarterly review? Now it’s a bomb. Now they’re blindsided. Now it’s adversarial. You did that to them by waiting.

Be proactive about org structure.

I try to evaluate the org chart as a whole at a minimum every six months. Not because I want to restructure constantly, but because companies change. The team that made sense six months ago might not make sense today. Someone might have left. A new product priority might have shifted the workload. You have to keep asking: does this still work?

I encourage all my leaders to think the same way. What if we lose someone? What criteria would we use for a reduction? Who’s underperforming? What’s our succession plan? These aren’t paranoid exercises. They’re responsible leadership. If you can’t answer those questions about your team, you’re not paying close enough attention.

Hire managers who have managed.

I mentioned this earlier, but I want to be clear about why. It’s not that first-time managers can’t succeed. The guy I told the story about earlier is proof of that. It’s that the failure rate is high, and most organizations don’t provide the level of support needed to make it work.

If you’re going to promote someone into their first management role internally, great. You have context. You know their strengths and gaps. You can build a development plan. But hiring an external candidate who has never managed before into a management role? You’re gambling. And the people who lose that gamble are the engineers on their team.

The Industry Has to Grow Up

I genuinely think this is the biggest unlock most engineering organizations are ignoring. Everyone’s talking about AI adoption, faster delivery, agentic development, new tooling. And those things matter. But none of them work if the management layer is incompetent.

You can’t build a high-performing engineering team on a foundation of absent leadership. You can’t adopt new practices if managers aren’t holding people accountable to old ones. You can’t move fast if half the team is disengaged because nobody’s ever told them what “good” looks like.

The industry has to grow up. Software management has to stop being an afterthought. It has to stop being the thing that happens by accident when someone good at coding gets promoted. It has to be intentional, and it has to be held to the same standard we hold everything else.

Because right now, the people paying the price are the engineers. And they deserve better than what most of them are getting.


Strangers on the Internet, or Why PRs Are Conversations, Not Notifications

Here’s something I say a lot that usually gets a reaction: we are not strangers on the internet.

The open-source PR model — push your work, notify the team, hope someone picks it up, iterate based on comments — makes total sense when contributors don’t know each other and are working across time zones and organizations with no shared context. It was built for that. It works great for that.

It does not work great for a team of people who sit (or video call) together every week, have shared context on the codebase, and are accountable to each other for delivery outcomes.

When I watch internal teams use the open-source model, I see a few things consistently:

PRs get big before anyone looks at them. The engineer works in isolation until they think the thing is done, then opens a PR with thirty changes. The reviewer now has to reconstruct the entire intent of the work from the diff. This is expensive for the reviewer, and the engineer has already invested too much to pivot meaningfully on structural feedback.

Reviews become rubber stamps or rabbit holes. Either the reviewer approves because the thing looks roughly right and they don’t want to slow it down, or they find a fundamental problem and now you have a PR comment thread that should have been a twenty-minute conversation three days ago.

Coverage and quality go sideways late. By the time someone notices a testing gap or an architectural issue, the engineer is context-switched out and getting back up to speed costs time neither of you wanted to spend.

The model I’ve had the most success with is straightforward: have the conversation early, stage the review, and use the PR to confirm shared understanding rather than initiate it.

Specifically — if you’re working on something that someone else will need to sign off on, loop them in before you start. “I’m going to do this thing. Here’s my plan. Any concerns?” Then, at the midpoint, show them the architecture — not the implementation details, just the structure. Names, boundaries, where things live. Get that directional feedback when it’s cheap to act on. Then finish the implementation and let the PR be the final confirmation: here’s what we talked about, here’s what I built, here’s the test coverage that says it works.

If the PR fails automated checks (coverage below threshold, build broken, linting issues) it doesn’t even need to get to a human. It goes back to the engineer with a clear signal. Fix the basics first. Don’t ask me to spend time on work that doesn’t meet the baseline.

PRs as the ends of conversations. It’s a small mental shift with a surprisingly large impact on how smoothly a team moves.


More Code, More Risk ... More Automation

One of the things I keep saying to engineering teams right now is: this tool should improve the process on all fronts. Not just the building. All of it.

AI-assisted development is genuinely remarkable. Engineers are shipping features faster, clearing backlogs that felt immovable, and getting real leverage from tooling that would’ve taken months to build before. I’m a fan. I’m actively encouraging it.

But faster output without better validation is just faster bugs. I’ve seen it — and heard it from peers managing teams at scale. Engineers trust the output, skip the second look, and something breaks in production. The specific failure mode varies. The root cause almost never does: the code moved faster than the confidence in it.

The issue isn’t that AI makes mistakes. It does, and so do humans. The issue is that when the volume of work goes up, the surface area for mistakes goes up with it. If your validation process doesn’t scale at the same rate, you end up cleaning up behind yourself constantly.

The answer isn’t to slow down. It’s to automate your safety net.

Fast builds. Fast test runs. Automated coverage thresholds that fail a PR before it ever hits a human reviewer. If the test coverage isn’t there, the PR doesn’t get reviewed. Period. That sounds harsh, but it’s actually generous — it tells the engineer clearly and immediately what they need to do before asking anyone else to spend time on their work.

I also think there’s something important here about how we use AI in the validation loop, not just the construction loop. Use it to generate test cases. Use it to review test coverage for gaps. Have it challenge your assumptions about how a feature might fail. A lot of what a good QA person does — thinking adversarially about software — can be augmented with the same tools you’re using to write the code.

The teams that win with AI aren’t the ones moving fastest. They’re the ones who figured out how to move fast and land cleanly.


Testing Is a Team Sport

I’ve had some version of this conversation with multiple engineering leaders lately, and I keep landing in the same place: quality is a team sport, and most teams haven’t figured that out yet.

Here’s the dynamic I see a lot. You’ve got developers who write their code, write their tests (maybe), and hand the whole thing off. Somewhere downstream, a tester or QA person picks it up and starts poking holes. When they find something, it goes back. When they don’t, it ships. Everyone’s doing their job. And yet somehow, bugs still make it to production, morale is still low, and the whole thing feels slower than it should.

The problem isn’t the people. The problem is the model.

Separating “building” from “quality” creates distance — between the person who knows the most about how something was constructed and the process of verifying that it works correctly. That distance is where bugs hide.

The fix isn’t to hire more testers. It’s to collapse that distance. Make the people accountable for delivery also accountable for correctness. Pair them up. If two engineers worked on a feature together, they’re both on the hook if it breaks. Not “well, they were supposed to test it.” No. Both of them own it.

What I’ve seen work is building that expectation into the culture from the top. Not as a punitive thing, but as a shared ownership thing. *We* built it. *We* stand behind it. If it’s wrong, we fix it, we learn from it, and we make sure it doesn’t happen that way again.

The corollary to this is that no single person (or department) in an org should carry “quality” as their sole responsibility. One QA lead against a team of fifteen engineers is not a quality strategy. It’s a bottleneck with a job title. The engineerings and their leadership (the people accountable for delivery) also have to be accountable for what they deliver working correctly. That’s not a radical idea. It’s just engineering maturity.

Quality isn’t a department. It’s an expectation.