|
| 1 | +Title: Git Image Diff with iTerm2 |
| 2 | +Date: 2021-02-14 12:37 |
| 3 | +Modified: 2021-02-14 12:37 |
| 4 | +Category: Posts |
| 5 | +tags: iterm,iterm2,git,terminal,shell |
| 6 | +cover: static/imgs/default_page_imagev2.jpg |
| 7 | +summary: iTerm has a imgcat function. Lets use it with Git for image diffing |
| 8 | + |
| 9 | +So iTerm2 has this neat `imgcat` command that allows you to "cat" or |
| 10 | +view an image right in the terminal. It's pretty sweet, but I had an |
| 11 | +idea: what if we used that with Git for diffing changed images in a |
| 12 | +`git diff`? |
| 13 | + |
| 14 | +This seems like it should be possible, you can replace what git does |
| 15 | +when you do a diff of two different binary files. For example, the |
| 16 | +[spaceman-diff package by Zach Holman](https://zachholman.com/posts/command-line-image-diffs/) |
| 17 | +does this to do a diff of two images as ascii art. |
| 18 | + |
| 19 | +We want to do the same, but instead of seeing an ASCII art version |
| 20 | +of an image, it'd be cool to see the two versions of the image itself |
| 21 | +right in the terminal. |
| 22 | + |
| 23 | +## Setting Git Attributes |
| 24 | + |
| 25 | +The first thing is create a file in your home directory called |
| 26 | +`~/.config/git/attributes`. In here you can define a mapping between file types |
| 27 | +and what command Git will run when doing a diff of those filetypes. In my case |
| 28 | +I entered the following: |
| 29 | + |
| 30 | +```config |
| 31 | +*.png diff=image |
| 32 | +*.jpg diff=image |
| 33 | +*.gif diff=image |
| 34 | +*.jpeg diff=image |
| 35 | +``` |
| 36 | + |
| 37 | +This tells git that when doing a diff of a file that ends with `png`, `jpg`, |
| 38 | +`gif`, or `jpeg` to use the `image` config. |
| 39 | + |
| 40 | +## Set Up The Image Config |
| 41 | + |
| 42 | +Now, in your `~/.gitconfig` file, add the following: |
| 43 | + |
| 44 | +```ini |
| 45 | +[diff "image"] |
| 46 | + textconv = imgcat |
| 47 | +``` |
| 48 | + |
| 49 | +This tells Git to use iTerm's `imgcat` script for converting the binary image |
| 50 | +file to text. This seems weird, but this is actually how iTerms imcat command |
| 51 | +works: it converts the binary image into a textual stream that iTerm knows how |
| 52 | +to understand and then render as an actual image. |
| 53 | + |
| 54 | +## Put imgcat In Your Path |
| 55 | + |
| 56 | +Next is put iTerm's `imcat` script somewhere on your path. You can download it |
| 57 | +from [here](https://iterm2.com/utilities/imgcat). Save that somewhere, make sure |
| 58 | +you chmod it to be executable (`chmod +x imgcat`), and then throw it into some |
| 59 | +directory on your path. You can confirm it's there by typing `imgcat` into an |
| 60 | +iTerm window: |
| 61 | + |
| 62 | +```shell |
| 63 | +$ imgcat |
| 64 | +Usage: imgcat [-p] filename ... |
| 65 | + or: cat filename | imgcat |
| 66 | +``` |
| 67 | + |
| 68 | +Note that you have to put this script in your path, you can't just rely on the |
| 69 | +version that's inlined into your terminal with iTerm's shell integration. |
| 70 | + |
| 71 | +## Profit |
| 72 | + |
| 73 | +Now when you change an image in a Git repo and do a `git diff` while in iTerm |
| 74 | +you'll see a preview of the original image and the changed image. Example: |
| 75 | + |
| 76 | + |
| 77 | + |
| 78 | +The above image is the original, the 2nd image is what I changed it to. Note |
| 79 | +that because imgcat is iTerm specific, it won't work in other terminals. If |
| 80 | +you do a `git diff` in a different terminal (ex: the integrated terminal in |
| 81 | +VS Code) you'll see just the ordinary blank output: |
| 82 | + |
| 83 | + |
0 commit comments