What is a dotfile — and why they were hidden by accident

You copied a project into a new folder:
cp -r my-app/* new-app/
You run it — and it can't find its API keys. Git says this isn't a repository at all. And node_modules suddenly wants into your commit.
Every file is there. Except the ones that start with a dot: .env, .git, .gitignore. The asterisk simply didn't notice them. These are dotfiles — and the story of why they're invisible is funnier than you'd think.
What a dotfile is
A dotfile is a file or folder whose name starts with a dot. .env, .gitignore, .zshrc, .ssh, .git.
They're usually settings, not content. You write them once and leave them alone. So the system hides them from normal listings to keep them out of the way.
They were hidden by mistake
Here's the surprising part. Nobody designed "hidden files" in Unix.
Every folder has two special entries: . (the folder itself) and .. (the folder above). To keep ls from showing them, early versions added a check. But the check only looked at the first character: starts with a dot — skip it.
Every name starting with a dot got caught in that net. Rob Pike, one of the Unix authors, has told this story. Programmers noticed that such files stayed out of the listing — and started putting settings there on purpose. A bug became a convention that's now half a century old.
Which leads to something important: a dotfile is not protected. It's not a password and not encryption. It just isn't shown in a listing by default.
Dotfiles you'll meet in a project
.env— secrets and environment settings: API keys, the database address. More in the article on environment variables..gitignore— the list of things git shouldn't commit..git/— the folder where the whole repository history lives. Delete it and the project stops being a repository..zshrcor.bashrcin your home folder — terminal settings. Every new window reads them. When changes to them take effect is covered in source vs running a script..ssh/— your SSH keys. The most valuable folder on your computer..DS_Store— Finder litter on a Mac. Add it to.gitignore: it reveals the file names in the folder.
How to see them
- Terminal:
ls -ashows everything, hidden included.ls -Adoes the same without.and... - Finder on a Mac:
Cmd + Shift + .toggles hidden files. - Windows: Explorer doesn't hide dot-names. There, hiding is a separate attribute, not part of the name.
- Code editor: VS Code and Cursor show dotfiles in the tree right away.
The asterisk trap
Back to copying. In the terminal, * doesn't match names starting with a dot — neither in bash nor in zsh. So:
cp -r my-app/* new-app/— loses.env,.git,.gitignore;mv * ../— leaves the dotfiles behind in the old folder;rm -rf build/*— doesn't touchbuild/.cache.
How to copy everything:
cp -r my-app/. new-app/
A dot instead of an asterisk means "the whole contents of the folder", hidden files included. Or copy the folder itself: cp -r my-app new-app.
Why it matters when you code with AI
Agents and assistants love the asterisk too. If an AI moves a project with a * command, .env stays behind. Then the app crashes with a key error even though the key is right there.
The opposite problem is worse. .env isn't visible in a listing — so it's easy to forget it exists when you publish the project. Before your first push, check that .env is in .gitignore. How to keep keys properly is covered in how to store API keys safely.
You can check this with two commands:
git check-ignore -v .env
git ls-files | grep env
The first should answer with the line from .gitignore that mentions .env. If it stays silent, the file isn't ignored. The second shows what git already tracks. If .env is there, adding it to .gitignore isn't enough: git keeps tracking the file. Remove it from the index with git rm --cached .env and rotate your keys — they're already in the history.
What are "dotfiles" on GitHub?
That's the name for repositories where people keep their terminal and editor settings: .zshrc, .gitconfig, .vimrc. On a new computer they clone it — and the environment is ready in a minute.
Can I just hide an important file with a dot?
No. That only hides it from the listing. Any program and anyone with ls -a will see it. Secrets need file permissions and .gitignore.
Why can't I see .env in my project?
Most likely it isn't there: you create it by hand, usually by copying .env.example. Check with ls -a in the project root.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





