125

Is it possible to track recursively all files contained in a folder and its subfolders with Git LFS ?

I would like to do something like this :

git lfs track myfolder/*
csa
  • 1,277
  • 2
  • 8
  • 8

2 Answers2

186

Use git lfs track "myfolder/**", with quotes to avoid the shell already expanding the pattern. All that the track command does is to write to .gitattributes, which in turn uses (almost) the same pattern matching rules as .gitignore, see the PATTERN FORMAT description.

sschuberth
  • 23,652
  • 5
  • 80
  • 125
  • I have tried this with subfolders, but only files and direct subfolders (like **myfolder/myfolder2/**) contained in **myfolder** are tracked, but not the files contained in the subfolders (like **myfolder/myfolder/myfile.png**). Thanks for your help – csa Mar 03 '16 at 12:59
  • 19
    Ah, you're probably a victim of shell expansion, i.e. `myfolder/**` was expanded by the shell before being passed to Git. I've updated my answer to add quotes, which should fix that. – sschuberth Mar 03 '16 at 13:04
  • 1
    `.gitattributes` does NOT follow (ALL) the same pattern matching rules as documented by the above git-scm link, otherwise "myfolder/**" could be replaced by "myfolder/" consistent with the statement "foo/ will match a directory foo and paths underneath it". I think (i.e. unconfirmed) "myfolder/" works in `.gitignore` because the ignore process descends through the file system stopping at a match but `.gitattributes` is checked against a pre-existing listing. If you find differently please add a comment with the git/git-lfs version that reversed this. – SensorSmith Jan 19 '18 at 15:56
  • No, it's not an error. As already explained in the linked PATTERN FORMAT, 'A leading "**" followed by a slash means match in all directories'. – sschuberth Jul 07 '18 at 15:41
  • `git lfs track "folder/**"` works recursively, verified on 2.19.windows.1 – Tamir Daniely Oct 17 '18 at 15:11
  • `git lfs track "folder/**"` definitely doesn't work for me. Did you verify this works if your files are further down, e.g. for a file `folder/foo/bar/blub.c`? I copied the same pattern that ended up in my .gitattributes into my .gitignore, and the files *are* successfully ignored. But not successfully tracked by git lfs (before I added the pattern to gitignore of course). This is with git 2.17.1. – Nir Friedman Oct 29 '18 at 21:53
  • 3
    Yes, this works for me, and according to the comments also for others. If you're on Windows, note that the command must be used from Git Bash, not from `cmd`. – sschuberth Oct 30 '18 at 08:07
  • **This worked for me:** `git lfs track Assets/Large\ Assets/\*\*` On ubuntu I had to escape both * and spaces and not use double quotes. – mzmrk Jan 06 '19 at 00:12
  • The [Atlassian help article](https://www.atlassian.com/git/tutorials/git-lfs#tracking-files) says that `git lfs track "Assets/"` will "track all files in the Assets directory and all subdirectories." Thus it is seemingly saying the solution should be `git lfs track "myfolder/"`, not `git lfs track "myfolder/**"`. Is that help article wrong, or is `**` wrong? – Senseful Jan 31 '19 at 00:28
  • 1
    Actually just tested it and it appears that that help center article is incorrect, and you want to use `git lfs track "myfolder/**"` as this answer suggests. More details and verification steps can be found in [this answer](https://stackoverflow.com/a/54452098/35690). – Senseful Jan 31 '19 at 06:35
  • 6
    I had to use `git lfs track "myfolder/**/*"` to make it work. – Luc Apr 12 '19 at 13:26
  • 3
    And I use `had to use git lfs track myfolder/**/*` without quotes on MacOS – DavidS1992 Apr 24 '20 at 17:40
3

This way you can track any folders with any subfolder. You want to recursively track folders with "n" number of folder and "m" number of sub-folders. I would recommend doing it this way.

  1. Find all the files extensions using following command
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u  
  1. and then creating a .gitattribute file and adding git lfs track syntax. This command generates that for you, it tracks all the files and its extensions and creates lfs tracking syntax.
find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u | awk '{print $1" filter=lfs diff=lfs merge=lfs -text"}' | sed 's/^/*./'
  1. Copy paste output to the .gitattribute file and commit.

It works for

  1. Any number of files and folder.
  2. Large repo with large number of small files which makes the repo size very big.
  3. Any number of folder and sub-folders.