.gitignore for macOS and Windows files

.DS_Store ._* .Spotlight-V100 .Trashes Thumbs.db [Dd]esktop.ini $RECYCLE.BIN/ *.lnk

The files macOS and Windows drop into your folders are .DS_Store, ._* resource forks, .Spotlight-V100 and .Trashes on volumes, Thumbs.db, desktop.ini and $RECYCLE.BIN/. Those are the key lines of the tool’s macOS and Windows templates, 29 lines together.

What the blocks ignore

  • macOS: .DS_Store, which the Finder writes into every folder it shows; ._*, the AppleDouble files that carry resource forks onto non-Mac volumes and into archives; and volume-root folders such as .Spotlight-V100, .Trashes, .fseventsd and .TemporaryItems.
  • Windows: Thumbs.db and ehthumbs.db thumbnail caches, desktop.ini folder settings, $RECYCLE.BIN/ on shared drives, Cygwin and MSYS *.stackdump crash files, and *.lnk shortcuts, which hold absolute paths.
  • Windows installers: *.cab, *.msi, *.msix, *.msm and *.msp.

None of these lines has a slash before its end, so each matches at any depth. 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:3:.DS_Store	docs/images/.DS_Store
.gitignore:7:._*	._logo.png
.gitignore:23:Thumbs.db	assets/Thumbs.db
::	thumbs.db
.gitignore:30:[Dd]esktop.ini	desktop.ini
.gitignore:30:[Dd]esktop.ini	Desktop.ini
.gitignore:35:*.msi	installer/setup.msi

Case matters, unless Git is told otherwise

Git matches case-sensitively, which is why the template writes [Dd]esktop.ini. Above, thumbs.db slips past Thumbs.db; with core.ignorecase on, as Git sets it on the usual case-insensitive Mac and Windows file systems, the same check matches:

.gitignore:23:Thumbs.db	thumbs.db

So a file that’s ignored on your laptop can show up in git status on a Linux machine.

Shipping an installer

If the repository really carries an .msi, re-include it after the template; it works because its folder isn’t excluded:

.gitignore:43:!installer/setup.msi	installer/setup.msi

A ! line can’t reach into an excluded folder such as $RECYCLE.BIN/, since Git never looks inside it.

Better in your global ignore file

These files come from your machine, not the project, so the usual home for them is one global file that covers every repository:

git config --global core.excludesFile ~/.gitignore_global

Without that setting, Git reads ~/.config/git/ignore, or $XDG_CONFIG_HOME/git/ignore. git check-ignore -v then names that file as the source. Keeping the lines in a project’s .gitignore as well still helps contributors who haven’t set one up.

.DS_Store files committed already?

.gitignore only affects untracked files. git ls-files -ci --exclude-standard lists the tracked files your ignore rules match; untrack them, keeping them on disk, and commit:

git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached
git commit -m "Stop tracking OS files"

Try it in the Gitignore Generator

In the file: macOS, Windows

.gitignore

2 templates · 29 pattern lines
# macOS
# The Finder writes one in every folder it shows
.DS_Store
.AppleDouble
.LSOverride
# Resource forks, written by older tools and by copying to a non-Mac volume
._*
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# Windows
# Thumbnail caches the Explorer keeps beside the images
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Written by Cygwin and MSYS programs when they crash
*.stackdump
# Folder view settings
[Dd]esktop.ini
# The Recycle Bin, on a shared or network drive
$RECYCLE.BIN/
# Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Shortcuts, which carry an absolute path
*.lnk
  • ✗Ignored by ".DS_Store" (macOS).

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.