Skip to content

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 be input or true.

    *.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

  1. Define the custom diff driver in your .git/config or global .gitconfig:

    [diff "markdown"]
        textconv = markdown-diff
    

  2. Create a script named markdown-diff that converts Markdown to a plain text format for comparison.

For word documents:

*.docx diff=word
This tells Git that any file that matches this pattern (.docx) should use the “word” filter when you try to view a diff that contains changes. What is the “word” filter? You have to set it up. Here you’ll configure Git to use the docx2txt program to convert Word documents into readable text files, which it will then diff properly. First, you’ll need to install docx2txt; you can download it from https://sourceforge.net/projects/docx2txt. Follow the instructions in the INSTALL file to put it somewhere your shell can find it. Next, you’ll write a wrapper script to convert output to the format Git expects. Create a file that’s somewhere in your path called docx2txt, and add these contents:
#!/bin/bash
docx2txt.pl "$1" -
Don’t forget to chmod a+x that file. Finally, you can configure Git to use this script:

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

  1. filter: Defines custom filters for content smudging and cleaning.

    *.doc filter=docx2txt
    
    Configure the filter in your .git/config:
    [filter "docx2txt"]
        clean = docx2txt-clean
        smudge = docx2txt-smudge
    

  2. ident: Expands $Id$ keywords in files.

    *.c ident
    

  3. linguist-language: Overrides the language detected by GitHub’s linguist tool.

    *.txt linguist-language=Text
    

  4. 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.

  1. Add to your .gitattributes:

    *.json diff=json
    *.json merge=json
    

  2. 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
    

  3. 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.