Back to Git & Dev Tools
2026-04-2910 min read

gitattributes (Git & Dev Tools)

Learn gitattributes (Git & Dev Tools) step by step with clear examples and exercises.

Why This Matters

In this full guide, we delve into Git attributes – a powerful tool that allows you to customize your Git project on a per-path basis. By understanding and utilizing Git attributes effectively, you can enhance productivity, avoid common pitfalls, and ensure consistency across your projects. Let's dive deeper!

The Importance of Git Attributes

Git attributes provide developers with the ability to define specific settings for individual files or directories within a repository. This feature is particularly useful when dealing with large-scale projects that involve multiple contributors working on different types of files, such as images, videos, executables, and configuration files.

By using Git attributes, you can:

  1. Enforce consistency: Ensure that all team members follow the same rules for handling specific file types.
  2. Optimize workflows: Automate certain tasks, such as text normalization or line ending conversion, to save time and reduce errors.
  3. Prevent accidental commits: Prevent sensitive files from being accidentally committed to the repository by marking them as binary.
  4. Simplify configuration management: Centralize configuration settings for your project in a single location (.gitattributes file).
  5. Improve collaboration: Streamline collaboration among team members by defining common rules and conventions for handling files within the repository.
  6. Optimize performance: Reduce the size of your repository by compressing or optimizing large binary files, such as images or videos.
  7. Maintain security: Protect sensitive information by marking certain files as filter or smudge, which can perform encryption or other security measures before committing them to the repository.

Prerequisites

Before diving into Git attributes, you should have a basic understanding of:

  1. Git fundamentals: Familiarity with Git commands like init, add, commit, and push.
  2. Git configuration: Understanding how to set user information (git config user.name and git config user.email) and global Git attributes (git config --global core.autocrlf).
  3. Gitignore files: Familiarity with using a .gitignore file to exclude certain files or directories from version control.
  4. Basic scripting: Familiarity with shell scripts or other programming languages, as you may need to create custom filters or smudge scripts for handling specific files or file types.
  5. Cross-platform development: Understanding how line endings can differ between operating systems (Windows, macOS, Linux) and the potential issues that can arise when working on cross-platform projects.

Core Concept

Git attributes are defined in the project's .gitattributes file, which resides in the Git directory (.git/info/) of your repository. This file allows you to specify custom settings for individual paths or file types using simple key-value pairs.

Here's a basic example of what a .gitattributes file might look like:

*.txt text=auto
*.jpg filter=myfilter

In this example, we've defined two attributes:

  1. text=auto: This sets the default text handling for all .txt files in the repository. Git will automatically convert line endings according to the user's global configuration (core.autocrlf).
  2. *.jpg filter=myfilter: We've specified that JPEG images should be processed by a custom filter named myfilter. This could be useful for compressing or optimizing images before they're committed to the repository.

Reserved Attributes

Git provides several built-in attributes that you can use to control various aspects of your project, such as text handling, filtering, and merging. Some common reserved attributes include:

  • text: Sets the text handling mode for a file or directory (auto, LF, CRLF).
  • binary: Marks a file as binary, preventing Git from attempting to track line endings.
  • smudge and clean: Custom scripts that are run when checking out or committing a file, respectively.
  • eol: Specifies the desired line ending style for text files (LF, CRLF, or native).

Defining Macro Attributes

In addition to built-in attributes, you can also create custom macro attributes using the attr.* syntax. This allows you to define complex rules for handling specific file types or patterns within your repository.

For example:

*.config attr.myconfig

attr.myconfig {
text eol=lf
-diff
}

In this example, we've defined a custom macro attribute named myconfig. This attribute is then applied to all files matching the pattern *.config, which will cause Git to convert line endings to LF (Unix-style) and suppress diff output when committing or merging changes.

Worked Example

Let's walk through a real-world example of using Git attributes in a project. In this case, we have an Android application that includes both Java source files and native library files (.so). We want to ensure that line endings are consistent across all files and prevent sensitive library files from being accidentally committed.

  1. First, create a .gitattributes file in the root of your repository:
*.java text=auto
*.so binary
  1. Set up a custom smudge script for native libraries to remove them from the working directory when checking out the repository:
#!/bin/sh

if git rev-parse --git-dir > /dev/null 2>&1; then
echo "Removing native library files..."
find . -type f -name '*.so' -print0 | xargs -0 rm -f
fi
  1. Save this script as remove_native_libraries in your project directory, and make it executable:
chmod +x remove_native_libraries
  1. Update the .gitattributes file to include the custom smudge script for native library files:
*.java text=auto
*.so filter=remove_native_libraries

Now, when you clone or check out this repository, the native library files will be automatically removed from your working directory. Additionally, Git will enforce consistent line endings for all Java source files.

Additional Optimizations

To further optimize the Android project, we can create a custom filter to compress images (.png and .jpg) before they're committed to the repository:

  1. Create a shell script named compress_images that uses an image compression tool like OptiPNG or JpegOptim to reduce the size of PNG and JPEG files, respectively.
  2. Update the .gitattributes file to include the custom filter for images:
*.png filter=compress_images
*.jpg filter=compress_images
  1. Make sure the compress_images script is executable and located in your project directory.

With these changes, Git will automatically compress images before committing them to the repository, helping to reduce its size and improve performance.

Common Mistakes

  1. Forgetting to define the .gitattributes file: Ensure that a .gitattributes file exists in the root of your repository and is properly committed.
  2. Incorrectly defining attributes: Double-check that the attribute definitions are correct and applied to the intended files or directories.
  3. Ignoring sensitive files: Make sure to mark any sensitive files (e.g., passwords, keys) as binary to prevent accidental commits.
  4. Overlooking line ending issues: Be aware of potential line ending inconsistencies when working with cross-platform projects or collaborating with team members using different operating systems.
  5. Not testing custom scripts: Always test your custom smudge and clean scripts thoroughly before committing them to the repository.
  6. Using outdated or incorrect filter scripts: Ensure that your custom filters are up-to-date and compatible with your project's requirements.
  7. Ignoring performance implications: Be mindful of the potential impact on build times, especially when using filters that process large files or directories.
  8. Not documenting Git attributes: Clearly document the .gitattributes file and any custom scripts used within it to help new team members understand the project's configuration.

Practice Questions

  1. What is the purpose of Git attributes, and why are they useful in a development workflow?
  2. How can you enforce consistent line endings for all text files in a repository using Git attributes?
  3. If you have a project that includes both source code (.java) and configuration files (.properties), how would you ensure that the .properties files are treated as binary by Git?
  4. You've created a custom smudge script for handling native library files in an Android project. How can you make sure this script is executed when checking out the repository?
  5. If you notice that line endings are inconsistent across your Java source files, what steps would you take to resolve the issue using Git attributes?
  6. You're working on a cross-platform project and want to ensure consistent line endings for all text files. What global Git configuration setting should you use, and how can you further enforce this consistency using Git attributes?
  7. Your team is collaborating on a large image-heavy project, and you want to optimize the repository size using Git attributes. What steps would you take to achieve this goal?
  8. You've created a custom filter script for compressing images in your project. However, you've noticed that the build times are significantly increased when running the script. What can you do to improve performance while still maintaining image compression?
  9. A new team member is joining your project and needs to understand how Git attributes are being used. How would you document this information for them?
  10. You're working on a sensitive project that requires certain files to be encrypted before they're committed to the repository. What steps would you take to implement this using Git attributes and custom scripts?

FAQ

  1. What happens if I forget to define a .gitattributes file for my project?
  • Without a .gitattributes file, Git will use its default settings for all files in your repository. This may lead to inconsistencies or errors, especially when working with non-text files or cross-platform projects.
  1. Can I apply Git attributes to individual directories within my repository?
  • Yes! You can define attributes for specific directories by adding them as subdirectories under the .gitattributes file. For example:
my_directory/ text=auto
  1. How do I handle line ending issues when working with cross-platform projects?
  • To ensure consistent line endings, you can set the global Git attribute core.autocrlf to either true (CRLF on Windows, LF everywhere else) or false (LF on all platforms). You may also need to define specific attributes for individual files or directories in your project's .gitattributes file.
  1. What are some common pitfalls to avoid when using Git attributes?
  • Some common mistakes include forgetting to define the .gitattributes file, incorrectly defining attributes, ignoring sensitive files, overlooking line ending issues, not testing custom scripts thoroughly before committing them to the repository, and not documenting Git attributes for new team members.
  1. Can I use Git attributes to optimize images or other large binary files in my project?
  • Yes! You can create a custom filter that compresses or optimizes images (or other binary files) when they're committed to the repository. This can help reduce the size of your repository and improve performance.
  1. How do I create a custom smudge script for handling native library files in an Android project?
  • To create a custom smudge script for native libraries, you would first write a shell script that removes the sensitive files from the working directory when checking out the repository. Then, you'd update your .gitattributes file to include the filter attribute and specify the path to your custom script.
  1. What is the difference between a smudge script and a clean script in Git attributes?
  • A smudge script is executed when files are checked out from the repository, while a clean script is executed when files are committed or staged for commit. Smudge scripts can be used to remove sensitive files or perform other actions before files are accessible in the working directory, while clean scripts can be used to prepare files for commit (e.g., by stripping whitespace or formatting code).
  1. How do I handle conflicts when using Git attributes with custom filters or smudge scripts?
  • When conflicts arise during merges or rebases, Git will first attempt to automatically resolve them using the default merge strategy for the affected files. If this fails, you'll need to manually resolve the conflict and commit the changes. In some cases, you may need to modify your custom filter or smudge script to better handle conflicts or ensure that they don't occur in the first place.
  1. Can I use Git attributes to enforce coding standards or best practices within my project?
  • Yes! You can create custom scripts that check for specific coding standards or best practices and refuse to commit changes that violate them. These scripts can be integrated into your project's .gitattributes file as either smudge or clean scripts, depending on when you want the checks to occur.
  1. How do I ensure that my custom Git attributes are compatible with other
gitattributes (Git & Dev Tools) | Git & Dev Tools | XQA Learn