A .NET / C# project produces a couple of build directories per project (bin/, obj/) and Visual Studio adds substantial per-developer state (.vs/, *.suo, *.user). The list above is a known-good modern set; this page explains the entries.
Build directories
[Bb]in/
[Oo]bj/
Every C# project generates bin/ (final output: DLLs, EXEs, dependencies) and obj/ (intermediate build artifacts). Both are large, platform-specific, and regenerable from source. Always ignore.
The [Bb] character class catches both bin/ and Bin/ — Visual Studio sometimes capitalizes inconsistently across projects. Same for Obj/.
In a multi-project solution, every project has its own bin/ and obj/. The single ignore pattern matches them all (it’s not anchored to the root).
Visual Studio user files
*.suo # Solution user options
*.user # Per-project user settings
*.userosscache
*.sln.docstates
.vs/ # Solution-level VS state cache
These files contain per-developer state — open documents, breakpoints, debug history. Sometimes hundreds of MB. Per-developer, per-machine. Never useful to commit.
The .vs/ directory is the modern Visual Studio working state. The *.suo was the equivalent in older VS versions.
Build configurations and outputs
# Build artifacts
*.pdb # Debug symbols (sometimes committed for production debugging — see below)
*.dll
*.exe
*.cache
TestResult/
TestResults/
*.coverage
*.coveragexml
*.pdb is contentious. PDB files are debugging symbols generated alongside DLLs. For development, ignore them. For shipped releases (where you want to debug crash dumps from production), some teams archive PDBs separately or commit them — but in the project repo itself, they’re build outputs and should be ignored.
*.dll and *.exe follow the same logic as the equivalent ignores in Java — build outputs.
NuGet
packages/ # Old-style NuGet package install location
*.nupkg
*.snupkg
.nuget/
project.lock.json # Old-style lockfile
Modern .NET projects use PackageReference (in the .csproj) instead of packages.config, so the packages/ directory is mostly historical. Still worth ignoring for legacy compatibility.
*.nupkg is a NuGet package file (a built-and-packed NuGet package). Generated by dotnet pack; not useful to commit.
ReSharper
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
ReSharper is the popular JetBrains plugin for Visual Studio. It generates per-developer cache and state.
*.DotSettings (without .user) is contentious — some teams commit a shared code style configuration; some don’t. The .user variant is always per-developer.
Rider
.idea/
*.iml
JetBrains Rider is the standalone .NET IDE. Same .idea/ ignore as IntelliJ-family IDEs.
Windows / IIS
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
These are Visual Studio configuration-and-platform output directories. Each combination of (Debug|Release) × (x86|x64|ARM|…) gets its own.
[Pp]ublish/
publish.profile.user
Publish profiles capture deployment settings. The .user version contains per-developer credentials; the non-user .pubxml is sometimes shared.
Logs
*.log
log.txt
Project-specific. The broad *.log pattern is common but may catch logs you actually want to keep. Adjust scope as needed.
OS files
.DS_Store
Thumbs.db
Standard.
ASP.NET Core specific
**/Properties/launchSettings.json # ⚠️ contentious
appsettings.*.local.json
secrets.json
launchSettings.json is contentious: it includes development URLs, environment variables, and launch profiles. Some teams commit it (shared dev setup); some ignore the user-specific entries.
secrets.json is for user secrets in development. Stored outside the repo by .NET’s secret manager, but stray copies sometimes appear.
Common pitfalls
- Forgetting
.vs/. It can grow to hundreds of MB. Add before opening the solution in Visual Studio. - Committing
bin/andobj/once. Once tracked,.gitignoredoesn’t untrack. Usegit rm -rf --cached bin objthen commit. - Ignoring
*.dllblindly while having a vendored DLL. A DLL committed for legitimate reasons (a third-party library not on NuGet) needs to be excepted with a negation:!libs/ThirdParty.dll. - Ignoring all
*.userfiles. The pattern is fine, but if a coworker usesWhateverProject.WhateverNotUser(some tools generate similarly-named files), be aware the broad pattern doesn’t catch them. - Forgetting publish output. First
dotnet publishproduces apublish/directory many MB in size. Ensure it’s ignored before publishing.
For other stacks, see Python, Node.js, Java, Go, Rust, Ruby, or the general .gitignore generator.