.gitignore decides what enters the repo; .gitattributes decides how Git treats what is in it. One small file at the root, and four annoyances quietly disappear.
Line endings that stop moving#
* text=auto eol=lf
Every text file normalizes to LF in the repo, whatever editor or OS committed it. The “whole file changed” diffs that come from a Windows checkout meeting an LF repo stop happening, and this line costs you nothing on day one of a repo.
Diffs that show what matters#
Lock files are for machines. Hiding their diffs keeps reviews on your code:
composer.lock -diff
package-lock.json -diff
The files still commit, still version, still deploy - they just stop producing thousand-line review noise. On GitHub, mark generated directories so they collapse by default and stay out of the language stats:
public/build/** linguist-generated=true
Hunk headers that name the function#
*.php diff=php
With the PHP diff driver, every hunk header in a diff names the method or function it sits in, not whatever line happened to be nearby. Reviewing git log -p on a large model gets noticeably easier.
Cleaner package downloads#
If any repo is ever installed as a Composer package, export-ignore keeps its development baggage out of other people’s vendor/:
/tests export-ignore
/.github export-ignore
/phpunit.xml export-ignore
End users download the code, not your CI.
None of this is mandatory and none of it changes what runs. It is housekeeping: the diffs get shorter, the reviews get faster, and the repo stops leaking its working files into places they never belonged.
Share this post
Keep reading
Annotating Commits with git notes: Metadata Without Rewriting History
Some things belong on a commit but not in it: review links, benchmark results, the ticket nobody remembered to reference. git notes adds them after the fact, no rebase required.
Backing Up Your Git Server So It Actually Restores
Every clone is a partial backup - but hooks, config and server state live outside the repo. Mirror, bundle, copy off-site, and rehearse the restore.
Cherry-Picking: One Commit Without the Branch
Cherry-pick copies a single commit onto your branch and leaves the rest behind. Right for hotfixes across release branches, wrong as a sync strategy.