gitgit-lfs

How to configure different Git LFS settings for subfolders?


I want to enable Git LFS for a certain file type repo-wide, but disable it in selected subfolders, i.e., accomplish a modular management of LFS in a Git repo.

As pointed out on https://git-scm.com/docs/gitattributes, in particular https://git-scm.com/docs/gitattributes#_examples, this should be possible by configuring dedicated .gitattributes files in the respective folders.

However, it does not work as aspected. If LFS is enabled in the root folder of the repo, disabling it in a subfolder has no effect. The other way round, disabling it top level and enabling it in a subfolder works.

I created a test repo with three .gitattributes files on different levels

TEST-PARTIAL-LFS
│   .gitattributes
│
├───lfs
│       .gitattributes
│       file_01.mat
│
└───no-lfs
        .gitattributes
        file_02.mat

The content of lfs/.gitattributes looks like this (enable lfs):

*.[mM][aA][tT] filter=lfs diff=lfs merge=lfs -text

The content of no-lfs/.gitattributes looks like this (disable lfs):

*.[mM][aA][tT] -text -diff -merge

However, the behavior is finally governed by the top level .gitattributes - but inconsistently.

If I use the disabling pattern in the top level file,

*.[mM][aA][tT] -text -diff -merge

then file_01.mat is added to LFS and file_02.mat is not - as aspected.

If I use the enabling pattern in the top level file,

*.[mM][aA][tT] filter=lfs diff=lfs merge=lfs -text

then file_01.mat is added to LFS and file_02.mat is too. Here, the disabling local pattern is ignored.

Any hints?

There is no $GIT_DIR/info/attributes.

I use git lfs ls-files to check LFS status. I use git version 2.45.2.windows.1.


Solution

  • When you use the enabling pattern in the top level file (*.mat filter=lfs) and disabling pattern in no-lfs/.gitattributes (*.mat -text -diff -merge) you don't disable filter attribute so it's inherited from the top-level .gitattributes. You can see it using git check-attr:

    $ git check-attr -a no-lfs/file_02.mat
    no-lfs/file_02.mat: diff: unset
    no-lfs/file_02.mat: merge: unset
    no-lfs/file_02.mat: text: unset
    no-lfs/file_02.mat: filter: lfs
    

    filter is set to lfs. You need to unset in no-lfs/.gitattributes:

    $ echo "*.[mM][aA][tT] -text -diff -merge -filter" >no-lfs/.gitattributes 
    
    $ cat no-lfs/.gitattributes   
    *.[mM][aA][tT] -text -diff -merge -filter
    
    $ git check-attr -a no-lfs/file_02.mat
    no-lfs/file_02.mat: diff: unset
    no-lfs/file_02.mat: merge: unset
    no-lfs/file_02.mat: text: unset
    no-lfs/file_02.mat: filter: unset
    

    Unset!