For VS Code, ignore what’s in .vscode/ with .vscode/*, then re-include the five kinds of file a team shares: settings.json, tasks.json, launch.json, extensions.json and *.code-snippets. Add .history/ and *.vsix, and you have the tool’s whole VS Code template, eight lines.
What is shared and what isn’t
settings.json: workspace settings such as the formatter or the TypeScript version. Personal ones, like your theme, belong in your User settings instead.tasks.jsonandlaunch.json: build tasks and debug configurations.extensions.json: the extensions VS Code recommends to anyone who opens the folder.*.code-snippets: project snippets.- Everything else in
.vscode/is ignored, such asc_cpp_properties.jsonwith machine paths or an SFTP extension’ssftp.jsonwith credentials..history/is the Local History extension’s folder, and*.vsixis a packaged extension.
In a scratch repository with this file, git check-ignore -v -n --no-index names the line that matched each path, or prints :: when none did:
.gitignore:4:!.vscode/settings.json .vscode/settings.json
.gitignore:7:!.vscode/extensions.json .vscode/extensions.json
.gitignore:8:!.vscode/*.code-snippets .vscode/react.code-snippets
.gitignore:3:.vscode/* .vscode/sftp.json
:: packages/web/.vscode/settings.json
:: app.code-workspace
Why .vscode/* and not .vscode/
.vscode/ excludes the folder itself, and Git never looks inside an excluded folder, so the ! lines after it do nothing:
.gitignore:3:.vscode/ .vscode/settings.json
.vscode/* only matches what’s inside, which leaves the folder open to the re-includes. Order matters too: each ! line must come after .vscode/*, because the last matching line wins.
The same goes for your global ignore file. With .vscode/ there, git check-ignore -v reports .vscode/settings.json against the global file, so a shared file you create never gets added from your machine.
Nested .vscode folders
.vscode/* has a slash before its end, so it only matches at the repository root: packages/web/.vscode/settings.json above matched nothing. In a monorepo, add **/ versions as custom lines:
.gitignore:16:!**/.vscode/settings.json packages/web/.vscode/settings.json
.gitignore:15:**/.vscode/* packages/web/.vscode/sftp.json
Committed the whole folder already?
.gitignore only affects untracked files. Untrack the folder, add it back, which keeps only the shared files, and commit:
git rm -r --cached .vscode
git add .vscode
git commit -m "Track only shared VS Code settings"
OS files
.DS_Store and Thumbs.db belong in a global ignore file, which is fine for files no project shares:
git config --global core.excludesFile ~/.gitignore_global