Michael Goerz
Michael Goerz

Reputation: 4460

Override .gitattributes from command line

Is there any way to temporarily override attributes in git, similarly to how -c can be used to override config options?

I would like to call git diff with a specific custom textconv command different from the one I normally use.

To make this more concrete: My actual use case is for Jupyter notebooks being edited in vim with the jupytext.vim plugin.

My normal ~/.gitconfig contains

[diff "jupyternotebook"]
    command = git-nbdiffdriver diff

that sets up nbdime as a diff driver, and then in ~/.gitattributes:

*.ipynb diff=jupyternotebook

Now I'd like to have

[diff "jupytext"]
    textconv = jupytext --from=ipynb --to=md -o - <

(or something like that) in the git config, and have git diff act as if

*.ipynb diff=jupytext

was in .gitattributes.

I'd be open to adding the [diff "jupytext"] section permanently to my ~/.gitconfig. However, using the "jupytext" driver instead of the default "jupyternotebook" must be temporary, based on a command line option passed to git diff.

Alternatively, I'd be OK with a command line option to git diff that forces it to use a different ~/.gitattributes file that takes precedence over all other .gitattributes files (e.g. in the same directory).

Ultimately, the command line option is intended to go into the g:gitgutter_diff_args setting of vim-gitgutter. I want to force the plugin to convert *.ipynb files differently from the way I would normally want to convert them with nbdime.

Upvotes: 10

Views: 1102

Answers (1)

Joshua Goldberg
Joshua Goldberg

Reputation: 5333

I had a similar case where I wanted to switch a textconv filter on and off per run, rather than by file extension. (I wanted to be able check sometimes if there are any changes that are not just a numeric change from one value to another.) The trick I found was to create a "default" case, which is always used, using cat for the textconv, and which I could then reassign with -c.

In my ~/.config/git/attributes I have:

* diff=default

In my ~/.gitconfig I have:

[diff "default"]
      textconv = cat
[diff "cat"]
      textconv = cat
[diff "nonums"]
      textconv = "f(){ gsed -E 's/[0-9]+/##/g'  \"$1\" ; }; f"

As well as this alias, letting me temporarily override the default case when desired by calling git diff-nonums. (The alias allows any arguments that git diff allows.)

[alias]
    diff-nonums = !git -c diff.default.textconv=\"`git config diff.nonums.textconv`\" diff

For your case, I think you'd want to use difftool, rather than diff's command configuration, to toggle the actual command. The nbdime docs show they provide a script to write the needed configs (git-nbdifftool config --enable [--global], and then can use git difftool --tool=nbdime) Having done that, I believe you could set up the default+alias trick to switch both the tool and textconv to do what you need for either nbdiff or jupytext.

(See man gitattributes, a few paragraphs down, for places where the attributes file may be saved. Note, I'm unclear about the difference between command, external, and difftool. For instance, I didn't find an easy way just now to get external or command to use git itself.)

edit I see from this question that git largely intends you to choose between textconv versus external commands, rather than mix/chain (unfortunately). I.e., the section in man gitconfig is called "Choosing textconv versus external diff". The linked question suggests a workaround with temporary files.

Upvotes: 4

Related Questions