.gitignore for VS Code

.vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/*.code-snippets .history/ *.vsix

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.json and launch.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 as c_cpp_properties.json with machine paths or an SFTP extension’s sftp.json with credentials. .history/ is the Local History extension’s folder, and *.vsix is 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

Try it in the Gitignore Generator

In the file: VS Code

.gitignore

1 template · 8 pattern lines
# VS Code
# Everything in .vscode except the five files below, which a team shares
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local history
.history/
# Built extensions
*.vsix
  • ✓Not ignored: "!.vscode/settings.json" (VS Code) is the last line that matches.

Lines are applied top to bottom, and the last one that matches wins — which is why a line of your own can overrule a template. This one was read as a file.

Runs in your browser. Nothing you enter is sent anywhere.