How it happens
Almost nobody commits a secret on purpose. The usual paths are mundane: a new repository where the ignore file was added after the first commit, a file named .env.production that the ignore pattern did not match, or a blanket "add everything" run in a hurry.
Automated tooling raises the odds. Anything that stages every changed file will stage a credential file the moment it stops being ignored.
Why deleting the file is not enough
Git keeps every version of every file it has ever been given. Removing the file in a later commit removes it from the working tree, not from history — anyone with a clone can read the old commit.
Rewriting history helps only for copies you control. Forks, local clones, and caches made before the rewrite still hold the original commit.
The real fix is rotation
Once a credential has been pushed, treat it as public. The fix is to revoke it at the provider and issue a new one. Everything else — rewriting history, deleting the repository — is cleanup, and none of it makes the old credential safe again.
Removing the cause
The durable answer is to stop needing env files to travel by hand. If the files live in one encrypted place and each machine pulls its own copy, there is no reason to email them, paste them into chat, or leave them where a commit can pick them up.
Keep the ignore rules too. The point is that they become a second line of defence instead of the only one.