2

I found a great Git function, which will unzip a file and use the uncompressed result in a diff, using .gitattributes, plus a change to your local repo config or to the global git config. This is how Simulink *.slx files are - they are zip compressed XML files, basically (maybe with some other added stuff).

However, this requires me to add a .gitattributes to every repo that needs this update - and it's config.

The particular changes needed are:

  1. Add the following line to .gitattributes:

    *.slx diff = slx
    
  2. Add the following lines to the local repo config (one method: git config -e):

    [diff "slx"]
        textconv = unzip -c -a
    

Question: Is there a way to apply the same function globally to any repo through the global config file, or another method?

The goal would be that if I set up the global function locally, Git would know to uncompress any *.slx file in any repo.

LightCC
  • 9,804
  • 5
  • 52
  • 92

1 Answers1

4

Edit: As LightCC found, you're supposed to be able to put these in your home .git/config/attributes or other file you set via core.attributesFile. Note that any existing .gitattributes entry can override any settings in core.attributesFile. The priority of competing entries is that those "closer to" the file override those "further away from" the file. For instance, if the directory's .gitattributes says *.ext a=b, this overrides the top work-tree directory .gitattributes setting of *.ext a=c, which overrides core.attributesFile *.ext a=d.

The short answer is no: you can define the diff textconv filter in your (personal, global-to-you) .gitconfig using, e.g., git config --global -e. However, you must have a .gitattributes per-repository.

It's worth adding that this idea of defining attributes in a .gitattributes (which has to be per-repository) but defining the drivers for them—whether they're textconv drivers for diff, merge drivers for git merge, or filter drivers for checkin/checkout—is a little bit broken, in my opinion at least. The problem is that the .gitattributes file gets copied automatically on git clone, but the drivers don't.

There's a fundamental security issue that prevents Git from having the drivers copied on clone, so this is reasonable. But it's clearly not a great situation. Note that gets around it by updating the per-repository configuration automatically; you can use the same sort of solution by running your own command, instead of git, that invokes Git while also fussing with your configuration.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thanks @torek - by drivers, do you mean the `config` textconv statement? – LightCC Jun 05 '19 at 17:58
  • 1
    Yes, or `[merge "foo"]`, or `[filter "foo"]`. Search [the gitattributes documentation](https://git-scm.com/docs/gitattributes) for the word "driver". – torek Jun 05 '19 at 18:08
  • 1
    Actually, after looking at the docs, I found there IS a global possibility (see `core.attributesfile`), but I can't get this working. There is [an answer that goes into more detail](https://stackoverflow.com/a/28027656/6501141). I set `core.attributesfile` to `~/.gitattributes`, and move `$repo/.gitattributes` to that location, and no conversion. Move it back into the repo, works again. Also tried `~/.config/git/attributes` location with `core.attributesfile` set to `true`. – LightCC Jun 05 '19 at 21:36
  • Oh, hm, you're right. This has been in since Git 1.7.4. It doesn't seem to work, although from a quick glance at the source, it *should* work. – torek Jun 05 '19 at 21:50
  • It's reading the file, but something is not passing right, it appears to be getting a null string or something. This is the error I'm getting (In the Diff output from Git Extensions) - if I add a second line ("*.slx merge = slx") I get a second error with line number 2 given: `is not a valid attribute name: C:/Users/210068178/.gitattributes:1` `is not a valid attribute name: C:/Users/210068178/.gitattributes:2` – LightCC Jun 06 '19 at 15:16
  • Okay, got it working - make sure you don't put spaces around the equals sign in your attribute definitions... `*.slx diff = slx` does not work, it must be `*.slx diff=slx`. Which means I had something else different broken the time I literally copied the working file from the repo... – LightCC Jun 06 '19 at 17:05