Skip to main content
The .gitattributes file allows you to specify attributes for paths in your repository. Attributes control various Git behaviors like line ending normalization, diff generation, merge strategies, and more.

Overview

Git attributes provide fine-grained control over how Git handles specific files. Common use cases include:
  • Line ending normalization (CRLF vs LF)
  • Custom diff and merge drivers
  • Binary file handling
  • Export behavior for archives
  • Language-specific diff patterns

File Format

Each line in .gitattributes follows this format:
pattern attr1 attr2 ...

Example

# Auto-detect text files and normalize line endings
* text=auto

# Declare text files
*.txt text
*.md text
*.js text

# Declare binary files
*.png binary
*.jpg binary

# Custom diff for specific files
*.json diff=json

File Locations

Repository .gitattributes

Location: Root or any directory in the repository
Scope: Shared with all users via version control
touch .gitattributes
git add .gitattributes
git commit -m "Add .gitattributes"

Per-Repository Attributes

Location: .git/info/attributes
Scope: Local to your repository, not shared

Global Attributes

Location: Configured via core.attributesFile
Scope: Applies to all your repositories
git config --global core.attributesFile ~/.gitattributes_global

Pattern Matching

Patterns use the same syntax as .gitignore:
# All files
*

# Specific extension
*.txt

# Specific file
README.md

# Directory
docs/**

# Files in specific directory
*.sh text eol=lf

Pattern Examples

# Match all .txt files
*.txt text

# Match only at root
/config.json text

# Match in any subdirectory
**/docs/*.md text

# Match entire directory
vendor/** binary

Attribute States

  • Set: text - Attribute is enabled
  • Unset: -text - Attribute is disabled
  • Set to value: eol=lf - Attribute has specific value
  • Unspecified: Attribute not mentioned
# Set text attribute
*.txt text

# Unset text attribute
*.bin -text

# Set with value
*.sh text eol=lf

Line Ending Handling

text

Controls line ending normalization:
Enable line ending normalization. Convert to LF in repository, convert on checkout based on core.eol or eol attribute.
*.txt text
*.md text
*.js text
Let Git automatically detect text files and normalize line endings.
* text=auto
This is the recommended setting for most repositories.
Disable line ending normalization. Files are stored and checked out as-is.
*.png -text
*.jpg -text

eol

Specify line ending style in working directory:
# Always use LF in working directory
*.sh text eol=lf
*.bash text eol=lf

# Always use CRLF in working directory
*.bat text eol=crlf
*.ps1 text eol=crlf
Values:
  • eol=lf - Use LF (Unix-style) line endings
  • eol=crlf - Use CRLF (Windows-style) line endings

Complete Line Ending Strategy

# Auto-detect text files
* text=auto

# Source code
*.js text eol=lf
*.ts text eol=lf
*.py text eol=lf
*.rb text eol=lf
*.go text eol=lf

# Shell scripts (Unix line endings)
*.sh text eol=lf
*.bash text eol=lf

# Windows scripts (Windows line endings)
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf

# Documentation
*.md text eol=lf
*.txt text eol=lf

# Binary files
*.png binary
*.jpg binary
*.gif binary
*.ico binary
*.pdf binary

Binary Files

The binary macro is equivalent to -text -diff:
# Using binary macro
*.png binary
*.jpg binary
*.zip binary

# Equivalent to
*.png -text -diff
*.jpg -text -diff
*.zip -text -diff

Common Binary Patterns

# Images
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.svg binary
*.webp binary

# Videos
*.mp4 binary
*.mov binary
*.avi binary

# Archives
*.zip binary
*.tar binary
*.gz binary
*.7z binary
*.rar binary

# Executables
*.exe binary
*.dll binary
*.so binary
*.dylib binary

# Documents
*.pdf binary
*.doc binary
*.docx binary
*.xls binary
*.xlsx binary

Diff Attributes

diff

Control how Git generates diffs:
Treat as text and generate normal diffs.
*.txt diff
Treat as binary. Shows “Binary files differ” instead of diff.
*.dat -diff
Use custom diff driver.
*.json diff=json
*.xml diff=xml

Built-in Diff Patterns

Git includes built-in diff patterns for many languages:
# Programming languages
*.c diff=cpp
*.cpp diff=cpp
*.h diff=cpp
*.java diff=java
*.py diff=python
*.rb diff=ruby
*.pl diff=perl
*.php diff=php
*.js diff=javascript
*.go diff=golang
*.rs diff=rust
*.cs diff=csharp

# Markup languages
*.html diff=html
*.css diff=css
*.md diff=markdown

# Data formats
*.json diff=json
*.xml diff=xml

# Other
*.tex diff=tex
*.sh diff=bash
These patterns improve hunk headers in diffs by showing relevant function/class names.

Merge Attributes

merge

Control merge behavior:
Use standard 3-way merge.
*.txt merge
Don’t merge, take version from current branch and mark as conflict.
*.db -merge
database.sqlite -merge
Use custom merge driver.
*.json merge=union

Built-in Merge Drivers

# Union merge: include lines from both versions
CHANGELOG.md merge=union

# Binary merge: keep ours on conflict
*.db merge=binary

Filter Attributes

filter

Apply filters when checking in/out files:
*.c filter=indent
*.jpg filter=lfs
Filters are configured in .git/config:
[filter "indent"]
    clean = indent
    smudge = cat

[filter "lfs"]
    clean = git-lfs clean -- %f
    smudge = git-lfs smudge -- %f
    process = git-lfs filter-process
    required = true

Git LFS Integration

Git Large File Storage (LFS) uses attributes to track large files:
# Track large files with Git LFS
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
Or use git lfs track:
git lfs track "*.psd"
git lfs track "*.ai"

Export Attributes

export-ignore

Exclude files from git archive:
# Don't include in exported archives
.gitattributes export-ignore
.gitignore export-ignore
.github/ export-ignore
tests/ export-ignore
*.test.js export-ignore
README.md export-ignore

export-subst

Expand placeholders in exported files:
version.txt export-subst
In version.txt:
Version: $Format:%H$
Date: $Format:%ai$
When exported, Git replaces $Format:...$ with actual values.

Common Configuration Examples

Basic Web Project

# Auto-detect text files
* text=auto

# Source code
*.html text eol=lf
*.css text eol=lf
*.js text eol=lf
*.json text eol=lf
*.md text eol=lf

# Images
*.png binary
*.jpg binary
*.gif binary
*.svg binary
*.ico binary

# Fonts
*.woff binary
*.woff2 binary
*.ttf binary
*.eot binary

# Archives
*.zip binary
*.tar binary
*.gz binary

Cross-Platform Project

# Normalize all text files
* text=auto

# Unix shell scripts
*.sh text eol=lf
*.bash text eol=lf

# Windows scripts
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf

# Source code (LF)
*.c text eol=lf
*.cpp text eol=lf
*.h text eol=lf
*.java text eol=lf
*.py text eol=lf

# Configuration files
*.json text eol=lf
*.xml text eol=lf
*.yaml text eol=lf
*.yml text eol=lf

# Documentation
*.md text eol=lf
*.txt text eol=lf

# Binary files
*.png binary
*.jpg binary
*.pdf binary
*.zip binary

Project with LFS

# Text files
* text=auto

# Source code
*.js text eol=lf diff=javascript
*.py text eol=lf diff=python
*.java text eol=lf diff=java

# Large files tracked by LFS
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.tar.gz filter=lfs diff=lfs merge=lfs -text

# Regular binary files
*.png binary
*.jpg binary

Unity Game Project

# Unity YAML
*.meta text eol=lf
*.unity text eol=lf
*.asset text eol=lf
*.prefab text eol=lf
*.mat text eol=lf
*.anim text eol=lf
*.controller text eol=lf

# Unity binary
*.cubemap binary
*.unitypackage binary

# 3D models
*.fbx binary
*.obj binary
*.blend binary
*.3ds binary

# Audio
*.mp3 binary
*.wav binary
*.ogg binary

# Textures
*.png binary
*.jpg binary
*.tga binary
*.psd binary

Working with Attributes

Check Attributes for a File

# Check specific attribute
git check-attr text README.md

# Check all attributes
git check-attr -a README.md

# Check multiple files
git check-attr text *.txt

Apply Attributes to Existing Files

After adding or changing .gitattributes, normalize existing files:
# Show what would be normalized
git add --renormalize --dry-run .

# Normalize all tracked files
git add --renormalize .
git status
git commit -m "Normalize line endings"

Best Practices

Start with text=auto

Use * text=auto as the first line to auto-detect text files

Be Explicit for Scripts

Always specify eol=lf for shell scripts and eol=crlf for Windows scripts

Mark Binary Files

Explicitly mark binary files to prevent corruption

Commit .gitattributes

Always commit .gitattributes to share settings with your team
# Auto-detect text files and normalize line endings to LF
* text=auto

# Explicitly declare text files
*.txt text
*.md text
*.json text
*.xml text
*.yaml text
*.yml text

# Scripts
*.sh text eol=lf
*.bash text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf

# Source code
*.c text eol=lf diff=cpp
*.cpp text eol=lf diff=cpp
*.h text eol=lf diff=cpp
*.java text eol=lf diff=java
*.py text eol=lf diff=python
*.js text eol=lf diff=javascript
*.go text eol=lf diff=golang

# Binary files
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary
*.zip binary
*.tar binary
*.gz binary
*.exe binary
*.dll binary
*.so binary

# Export settings
.gitattributes export-ignore
.gitignore export-ignore
.github/ export-ignore
tests/ export-ignore

Troubleshooting

Line Endings Still Wrong

Problem: Line endings aren’t being normalized Solution: Re-normalize the repository:
# Remove everything from index
git rm -rf --cached .

# Re-add all files
git add .

# Commit normalized files
git commit -m "Normalize line endings"

Binary Files Showing Diffs

Problem: Binary files showing garbled diffs Solution: Mark them as binary:
*.png binary
*.jpg binary
*.pdf binary

Check Current Attributes

# See what attributes Git sees for a file
git check-attr -a path/to/file

# See where attribute is defined
git check-attr --source text path/to/file

See Also