Git Attributes Binaries
Demonstrates using Git to provide rich attribute metadata for binary files.
# 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 # ☿ 🜔 🜍 🜂 🜃 🜁 🜄