We'll work a bit with the .gitattributes
file in this kata. In this file, you're able to specify how git handles files, e.g., if they
are binary or text files. For instance, it's possible to describe what type of
line ending that should be used, or if you have some binary files in your repository,
you can specify what program that should be used for showing the diff. The following exercises
are for GNU/Linux platforms and Mac.
- Run
source setup.sh
(or.\setup.ps1
in PowerShell)
-
Create a
.gitattributes
file with the following content:*.txt text=auto eol=lf working-tree-encoding=UTF-8
-
Run
git add file1.txt .gitattributes
and you should seewarning: CRLF will be replaced by LF in file1.txt.
-
Try to experiment changing
eol
to eitherauto
orcrlf
. Can you explain why only one of them changes the line endings of the file, i.e., gives a similar warning as above. -
Some files must have DOS (CRLF) line endings in order to work. One such example is bat-files, e.g., Jenkins requires the line endings in bat-files to be CRLF before being able to run them.
*.bat text=auto eol=crlf
A similar problem is present with Linux scripts using a shebang in the first line to point to an interpreter. GNU/Linux systems will have a problem running them, e.g.,
bash\r
is not recognized as an interpreter.Note: The line endings can also be controlled through
git config
but that is a different topic. -
Git is mostly suitable for text files, but it can also handle binary files and you can set programs to show the diff. In this example, we are going to use the command line tool
exiftool
to show and compare meta-data for iamges. You will need to have this tool installed for the example to work. (There is also a similar tool called justexif
which would also work, but only forjpg
files). If you don't have exiftool already it is usually quite easy to install with your favorite package manager e.g.brew install exiftool
orapt install exiftool
Once we have exiftool installed, we will need to configure a new "diff driver" in the git config that uses exiftool to "convert" a binary file to a text representation that can be diff'ed.
Add the following to your global ~/.gitconfig or to the local .git/config file.
[diff "useexif"] textconv = exiftool cachetextconv = true
Then we need to actually tell Git to use this new "driver" for any files of the type
PNG
. Add the following to the .gitattributes file you created at the start of the exercise:*.png diff=useexif
-
Now that everything is set up, let us test it out. You can use the image mario.png located next to this README file. ( Mario png borrowed from https://www.freepngimg.com/download/mario/20698-7-mario-transparent-background.png )
Copy/move this image to the exercise folder (e.g. with
cp ../mario.png .
), then usegit add
to stage the image and put it under Git's control.Now we can run
git diff --staged
to view the change, and hopefully Git will print out the fullexiftool
output in green as it is comparing to the previous (non-existing) /dev/null version. -
To really see the value, replace the image with a different one, e.g., using the smaller version of the image also in this folder:
If you copy this file to the exerise folder and rename it to
mario.png
Git will correctly see it as a changed file. (you can do this easily usingcp ../mario-small.png ./mario.png
to get the smaller one and overwrite the existing)Now, just run the regular
git diff
to have Git compare the new smaller one with the original that is currently staged. It should be easy to see which attributes of the image were changed in the resize.
file file1.txt
(on GNU/Linux and Mac)git add
git status
iconv
is useful for converting between different character encodings.
The .gitattributes
has another alternative, if you are just interested in
having the same line endings and character encodings across the files in your
repository. editorconfig can handle indentation
size (useful for Python), whether to use tabs or spaces, adding a final newline
etc.