Attributes
Git attributes are a powerful feature of Git that allow you to define how different types of files are handled by Git in various operations, such as merging, diffing, and exporting. Git attributes are configured in a file named .gitattributes
located at the root of your repository or in any subdirectory or in the .git/info/attributes file if you don’t want the attributes file committed with your project..
The basic syntax for defining attributes in a .gitattributes
file is:
<pattern> <attribute> [value]
-
<pattern>
: A glob pattern that matches one or more files. -
<attribute>
: The name of the attribute to set. -
[value]
: An optional value for the attribute (e.g.,true
,false
,unset
).
Common Git Attributes
Text Attributes
-
text
: Normalizes line endings for text files.*.txt text
-
crlf
: Controls the line-ending conversion. Can beinput
ortrue
.*.sh text eol=lf
Example: Normalizing Line Endings
Ensure consistent line endings by normalizing text files to LF in the repository:
*.txt text
*.sh text eol=lf
*.bat text eol=crlf
Binary Attributes
binary
: Marks files as binary to prevent diff and merge operations.*.jpg binary
Example 2: Marking Files as Binary
Prevent diff and merge operations on binary files:
*.jpg binary
*.png binary
Diff Attributes
diff
: Customizes how diffs are generated for specific file types.
Example: Custom Diff Drivers
Define a custom diff driver for Markdown files:
1. Add the following to your .gitattributes
:
*.md diff=markdown
-
Define the custom diff driver in your
.git/config
or global.gitconfig
:[diff "markdown"] textconv = markdown-diff
-
Create a script named
markdown-diff
that converts Markdown to a plain text format for comparison.
For word documents:
*.docx diff=word
#!/bin/bash
docx2txt.pl "$1" -
git config diff.word.textconv docx2txt
Now Git knows that if it tries to do a diff between two snapshots, and any of the files end in .docx, it should run those files through the “word” filter, which is defined as the docx2txt program. This effectively makes nice text-based versions of your Word files before attempting to diff them.
Merge Attributes
merge
: Specifies custom merge strategies.*.lock merge=ours
Example: Custom Merge Strategies
Use a custom merge strategy for lock files:
*.lock merge=ours
Add the following to your .git/config
or global .gitconfig
:
[merge "ours"]
driver = true
Export Attributes
export-ignore
: Excludes files from archive operations.secret.txt export-ignore
Example: Exporting Archives
Exclude certain files from git archive
operations:
secret.txt export-ignore
*.log export-ignore
Additional Attributes
-
filter
: Defines custom filters for content smudging and cleaning.Configure the filter in your*.doc filter=docx2txt
.git/config
:[filter "docx2txt"] clean = docx2txt-clean smudge = docx2txt-smudge
-
ident
: Expands$Id$
keywords in files.*.c ident
-
linguist-language
: Overrides the language detected by GitHub’s linguist tool.*.txt linguist-language=Text
-
whitespace
: Customizes how whitespace errors are flagged.*.py whitespace=fix
Practical Use Case
Use Case: Custom Diff and Merge for JSON Files
Suppose you frequently edit JSON files and want a custom diff and merge strategy that pretty-prints JSON before comparing or merging.
-
Add to your
.gitattributes
:*.json diff=json *.json merge=json
-
Define the custom diff and merge drivers in your
.git/config
:[diff "json"] textconv = jq . -M [merge "json"] driver = jq -s '.[0] * .[1]' %O %A %B > %A
-
Ensure you have
jq
installed, a lightweight and flexible command-line JSON processor.
Conclusion
Git attributes provide a versatile way to customize how Git handles different types of files in your repository. By using the .gitattributes
file, you can define specific behaviors for text normalization, binary handling, custom diff and merge strategies, export rules, and more. Understanding and utilizing these attributes effectively can greatly enhance your workflow and ensure consistent handling of files across different environments.