Boneyard Tools

How .gitattributes controls text, LFS and Linguist

What a .gitattributes file does, how text=auto normalizes line endings, and how filter=lfs and linguist rules change a repo's behavior.

What a .gitattributes file is

A .gitattributes file lets you attach settings to path patterns in a Git repository. Each line pairs a pattern (like '*.psd' or 'vendor/**') with one or more attributes such as 'text', 'filter' or 'export-ignore'. Git reads the file from the repo root and applies the matching attributes whenever it checks files in or out. Because the file is committed alongside your code, every teammate and every clone gets the same behavior, which is why it is the right place for rules that must be consistent across machines.

Line-ending normalization with text=auto

The line '* text=auto' tells Git to detect text files and store them with LF endings in the repository, then check them out with whatever your operating system prefers. Windows contributors keep their CRLF working copies while the committed history stays clean, which stops the whole-file diffs that appear when line endings flip. It is a safer default than relying on the per-user core.autocrlf setting because the rule travels with the repository instead of depending on each developer's local config.

Tracking big files with Git LFS

Binary assets like PSDs, videos and archives bloat Git history because every edit stores a full new copy. Git LFS replaces those files with small text pointers and keeps the real bytes on a separate LFS store. A tracking line such as '*.psd filter=lfs diff=lfs merge=lfs -text' routes matching files through the LFS filter and marks them non-text so Git does not try to diff or merge them line by line. Remember that LFS must be installed with 'git lfs install', and the tracking rules only apply to files committed after the .gitattributes is in place.

Linguist and archive rules

GitHub uses a library called Linguist to guess a repository's languages for the colored bar on its page. Marking a path 'linguist-vendored' removes bundled third-party code from that calculation so your own language mix shows through. Separately, 'export-ignore' controls 'git archive': any matching path is dropped from the tarball or zip that command produces, which is handy for keeping tests, CI config and development scaffolding out of release downloads. Both rules are declarative, so they take effect the moment the file is committed.

Frequently asked questions

Where does the .gitattributes file go?

Place it in the root of your repository and commit it. You can also add a .gitattributes inside a subfolder to override rules for that folder, but the root file is the usual home for repo-wide settings.

Will text=auto fix files that are already committed?

Not automatically. New commits follow the rule, but existing files keep their stored endings until you renormalize, for example by running 'git add --renormalize .' and committing the result.

Do LFS rules migrate files that were already committed normally?

No. Adding an LFS pattern only affects future commits. To move history into LFS you need a rewrite with 'git lfs migrate', which changes commit hashes.