Published January 15, 2020
Updated February 16, 2020
Git Attributes Binaries
Demonstrates using Git to provide rich attribute metadata for binary files.
Transcript
# Hello and welcome to the Alchemists Screencasts!
# Today, we'll leverage the power of Git attributes for managing binary files.
# A practical example is best so here's a Git repository with an icon:
tree
# The icon.png is a binary file, which Git does not handle well.
# In fact, consider storing binaries *outside* your Git repository.
# The reason is binaries can't be diffed and cause repository bloat over time.
# Warning aside, let's say you have a repository with binaries.
# What happens when you want to compare or view these file?
# To start, we'll use GraphicsMagick (http://www.graphicsmagick.org) via Homebrew:
brew install graphicsmagick
# Now we can use GraphicsMagick to resize our icon to 10x10 pixel resolution:
gm convert -resize "10x10" icon.png icon.png
git diff
# I don't know about you, but that's not terribly helpful. 😅
# Let's install the ExifTool (https://exiftool.org) to enhance Git:
brew install exiftool
# Next we'll teach Git to use ExifTool via the attributes file.
printf "%s\n" "*.png diff=exif" > .git/info/attributes
# With that change in place, let's see what Git diff says:
git diff
# Notice, amongst other metadata, the image width, height, and size changes.
# We can see the image was correctly resized from 57x57 to 10x10 pixels.
# With Git attributes in place, Git show is enhanced as well:
git show icon.png
# Definitely an improvement over the one line output from earlier. 🎉
# The opposite is possible as well.
# First, let's throw away our changes:
git reset --hard HEAD
# Let's say you have a file you want Git to interpret as binary:
printf "%s\n" "<data>" > tutorial.data
git add tutorial.data
git commit --message "Added tutorial data"
printf "%s\n" "<updated data>" > tutorial.data
git diff
# Now we can treat this file as binary.
printf "%s\n" "*.data binary" >> .git/info/attributes
git diff
# Again, be cautious with this approach as binary files lead to repository bloat.
# While we've only been using Git attributes for the local project:
cat .git/info/attributes
# Changes like this are best applied globally.
# Here's my global configuration (Git adheres to the XDG Directory Specification):
cat ~/.config/git/attributes
# In addition to ExifTool capabilities, I've tought Git about Ruby too.
# Notice the use of `diff=ruby` for the various, non-obvious, Ruby files.
# This allows me to compare differences in Ruby syntax.
# You can also use:
touch .gitattributes
# (alternative to `.git/info/attributes`, though the global form is recommended)
# Lastly, you can use custom attributes should the default not be desired:
git config --add core.attributesFile path/to/custom/file
# For more on attributes, see: https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes
#
# Enjoy!
# https://alchemists.io
# ☿ 🜔 🜍 🜂 🜃 🜁 🜄