Introduction​
A .gitattributes
file is used to define specific attributes for files and paths within a Git repository. It
helps control:
- Line endings (ensuring consistency across OSes)
- Binary file handling (preventing corruption)
- Diffing and merging (customizing how Git treats specific file types)
- Git Large File Storage (LFS) (managing large files efficiently)
By using .gitattributes
, you can maintain consistent file handling across different environments, reduce merge
conflicts, improve collaboration, and optimize repository size.
It's best practice to always include a .gitattributes
file in your repository.
Common Attributes​
Line Endings​
Different operating systems use different newline characters:
- Windows: Carriage Return + Line Feed (CRLF)
- Linux/macOS: Line Feed (LF)
This inconsistency can cause "phantom" changes in Git, leading to unnecessary merge conflicts and breaking scripts.
The .gitattributes
file ensures uniform line endings regardless of individual developers' settings and overrides
the core.autocrlf
Git configuration setting.
Attributes:
text=auto
: Automatically detects text files and normalizes line endings. Git uses internal heuristics (usually very reliable) to determine if a file is text or binary.eol=lf
: Converts line endings to LF (recommended for most projects, ensuring consistency).eol=crlf
: Converts line endings to CRLF (only for files that require it, like Windows batch scripts).-text
: Marks a file as binary, preventing line ending conversion. Git will still try to diff these files unless you also use-diff
.
Use text=auto eol=lf
as your baseline. This, combined with a developer's core.autocrlf
setting (often true
on
Windows, or input
for cross-platform), provides the most robust and flexible solution. The repository always stores
files with LF line endings, while developers can work with their preferred line endings locally.
Example .gitattributes
Configuration:
####################################################################################################
# Git Line Endings #
####################################################################################################
# Auto detect text files and perform LF normalization
* text=auto eol=lf
# Force batch scripts to always use CRLF line endings so that if a repo is accessed in Windows via a
# file share from Linux, the scripts will work.
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
# Force bash scripts to always use LF line endings so that if a repo is accessed in Unix via a file
# share from Windows, the scripts will work.
*.sh text eol=lf
Large File System (LFS)​
Storing large files directly in Git bloats the repository, making clones and fetches slow. Git LFS stores
large files separately (on a dedicated LFS server), keeping only small pointer files in the Git repository.
This drastically improves performance for repositories with large assets.
Attributes
filter=lfs
: Marks files for Git LFS tracking.diff=lfs
: Uses Git LFS for diffs (shows changes to the pointer file, not the large file content).merge=lfs
: Uses Git LFS for merging (handles merging of the pointer files).
Example .gitattributes
Configuration:
####################################################################################################
# Git Large File Storage (LFS) #
####################################################################################################
# Archives
*.7z filter=lfs diff=lfs merge=lfs -text
*.br filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.tar filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
# Documents
*.pdf filter=lfs diff=lfs merge=lfs -text
# Images
*.gif filter=lfs diff=lfs merge=lfs -text
*.ico filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.webp filter=lfs diff=lfs merge=lfs -text
# Fonts
*.woff2 filter=lfs diff=lfs merge=lfs -text
# Other
*.exe filter=lfs diff=lfs merge=lfs -text
Binary Files (Without LFS)​
If you aren't using LFS, it's crucial to explicitly tell Git which files are binary. Git might misinterpret binary files as text, leading to corruption during line ending normalization or generating very large, unreadable diffs.
Attributes:
-text
: Prevents line ending conversion.binary
: Equivalent to-text -diff
(prevents both line ending normalization and diffing). This is the recommended way to mark binary files if you're not using LFS.-diff
: Specifically disables diffing (useful even without-text
).
Example .gitattributes
Configuration:
####################################################################################################
# Binary Files #
####################################################################################################
# Treat common binary formats as binary files (disable text conversion and diffing)
*.png binary
*.jpg binary
*.gif binary
*.zip binary
*.pdf binary
*.exe binary
*.dll binary
*.mp3 binary
*.mp4 binary
Best Practices Summary​
- Always use a
.gitattributes
file in your repository. - Use
text=auto eol=lf
as your baseline for most files. - Explicitly mark binary files with
binary
or-text -diff
. - Use Git LFS for large files.
- Use
git check-attr
to verify your settings. - Commit and push your
.gitattributes
file! It's a critical part of your repository's configuration. - Use subdirectory
.gitattributes
files for granular control within large projects.