The Hidden Gem in Git - .git/info/exclude

By Nabeel Parkar
Git Development Tools Productivity Best Practices

The Hidden Gem in Git: .git/info/exclude

If you've ever worked in a shared or open source repository, you've probably run into this problem: your local setup needs a few files ignored, but the project's .gitignore doesn't allow it. Maybe you use a different editor than the rest of the team, or you're experimenting with a new AI-powered tool that generates its own config files. You don't want to clutter the global ignore list or accidentally commit personal settings — but you also don't want those files showing up in git status every time.

Consider these scenarios:

  • You clone an OSS project that doesn't ignore .vscode/ or .idea/ folders because the maintainers don't want to favor a specific IDE. You, however, rely on VS Code and want to keep your workspace clean.
  • You're trying out an AI-assisted coding tool like Claude Code or Cursor, which creates helper files and directories such as .claude/, .cursor/, CLAUDE.md, or AGENTS.md. The project hasn't standardized on any of these yet — or maybe they're using something else entirely.

In both cases, you need a way to ignore files locally without pushing those rules to remote. Fortunately, Git already provides a built-in solution: the .git/info/exclude file.


Understanding .git/info/exclude

Git automatically creates a hidden .git directory inside every repository to store metadata and configuration. Within it, you can have an info directory containing an exclude file that behaves just like a .gitignore—but it only applies to your local clone.

By default, the info directory and exclude file don't exist, so you may need to create them manually:

mkdir -p .git/info
touch .git/info/exclude

Once created, you can add ignore patterns just as you would in .gitignore:

# Ignore local IDE settings
.vscode/
.idea/

# Ignore personal environment files
.env.local

This approach is ideal for files you never want to commit but also don't want to affect anyone else's clone of the repository.


Making It Convenient: .gitignore.local

While .git/info/exclude works great, it's hidden deep in the .git folder and easy to forget. A simple improvement is to create a .gitignore.local file at the root of your project and link it to .git/info/exclude:

ln -s .git/info/exclude .gitignore.local

Now you can manage local ignore rules directly from the root directory. To prevent the file itself from showing up in git status, add this entry inside it:

.gitignore.local

With this setup, your local ignore configuration becomes visible, accessible, and neatly isolated from version control.


Putting It Together

Here's a small script you can run in the root of any Git repo to set this up quickly:

#!/usr/bin/env bash
# setup-local-gitignore.sh

# ensure we are in a git repo
if [ ! -d .git ]; then
  echo "This does not look like a Git repository (.git missing)." >&2
  exit 1
fi

# create info dir and exclude file if missing
mkdir -p .git/info
[ -f .git/info/exclude ] || touch .git/info/exclude

# create a convenient symlink in the repo root
if [ ! -L .gitignore.local ] && [ ! -f .gitignore.local ]; then
  ln -s .git/info/exclude .gitignore.local
fi

# ensure the local file ignores itself
if ! grep -qx ".gitignore.local" .git/info/exclude; then
  echo ".gitignore.local" >> .git/info/exclude
fi

echo "Local ignore setup complete. Edit .gitignore.local to add your patterns."

If you find yourself doing this often, add a helper to your shell config (~/.bashrc or ~/.zshrc):

# Add to ~/.bashrc or ~/.zshrc for quick setup in any repo
localgitignore() {
  # Use local variables to avoid polluting shell scope
  local repo_root="${1:-.}"
  local current_dir="$(pwd)"

  # Navigate to the target repo directory
  cd "$repo_root" || return 1

  # Ensure .git/info/exclude exists
  mkdir -p .git/info
  [ -f .git/info/exclude ] || touch .git/info/exclude

  # Create the symlink if missing
  if [ ! -L .gitignore.local ] && [ ! -f .gitignore.local ]; then
    ln -s .git/info/exclude .gitignore.local
  fi

  # Make sure the file ignores itself
  if ! grep -qx ".gitignore.local" .git/info/exclude; then
    echo ".gitignore.local" >> .git/info/exclude
  fi

  # Return to the original directory
  cd "$current_dir"

  echo "Local gitignore ready in $repo_root/.gitignore.local"
}

Then you can run:

localgitignore

in any repo to enable local-only ignore rules.

Summary

If you ever need to ignore files locally without modifying the main .gitignore, .git/info/exclude is the perfect solution. And with a .gitignore.local symlink, you make it both visible and easy to edit—all while keeping your repository clean and collaboration-friendly.

Simple, practical, and entirely Git-native.