Search code examples
gitgit-lfsgit-lfs-migrate

How to Add GIT LFS to existing repo with multiple branches?


There are tons of documentations about adding GIT LFS to a new REPO. But what if I have an existing Repo with mutlitple Branches like main, dev, featurex12? (Info: There are currently no Large Files in my Repo)

Do I still work on the dev branch and use:

git lfs track "*.png"
git add .gitattributes

and after pushing, do I just merge the new lfs branch into my main branch or do I have to do this on every branch?


Solution

  • It depends on whether you already have those types of files in the repository, and whether you want to migrate any existing files into LFS.

    As a general rule, you want the gitattributes file to be in place before the LFS files show up in a commit.

    The gitattributes file specifies which files should have the filters (clean & smudge) applied to them. When you run

    git lfs track *.png
    

    it adds rules to the gitattributes file specifying that the LFS filter should be used:

    *.png filter=lfs diff=lfs merge=lfs -text
    

    That’s how files get into LFS when you use git-add/git-commit, and how they get back out when you use git-checkout. When you add a file, the LFS “clean” filter converts it to an LFS pointer file and it gets staged to the index. When you commit, that pointer gets saved to the repository. When you checkout, the LFS “smudge” filter uses the LFS pointer file to retrieve your original file contents.

    Git will use whatever gitattributes file it finds in the working tree, regardless of whether it’s committed to the repository. In other words, those settings will become active as soon as you run git lfs track *.png.

    So, if you commit the gitattributes file (specifying that png files should be tracked by LFS) on your “dev” branch, when you move to your “master” or “featurex12” branch, that version of gitattributes won’t be there and git will not apply the LFS filters. You can merge those other branches with “dev” so the gitattributes will be applied on those other branches. To get LFS to be applied on all the other branches, you need that gitattributes file to be committed to them. You can accomplish that your merging and rebasing. I personally don’t recommend re-committing the gitattributes file on multiple branches because that can cause weird conflicts when/if you merge those branches together. However, it will probably work. You would just want to make sure that it’s EXACTLY the same everywhere.

    This is where you have to worry about existing png files in the repository. If you have png files in the master branch, and then you set png files to be tracked by LFS in the dev branch, when you merge them together (or rebase one onto the other) you’ll end up with a commit containing a gitattributes file telling git to use the LFS filters on png files, and simultaneously you’ll have png files that are not actually in LFS. This won’t be catastrophic, but it will cause error messages to be thrown at you. To deal with this, you’d need to migrate the png files into LFS:

    git rm --cached *.png
    git add *.png
    git commit
    

    Those commands cause git to reapply the filters, effectively migrating the files into or out of LFS (depending on the gitattributes file currently in the working directory).

    Now, if you want to migrate historical files (all previous versions of png files in all previous commits), you’ll need to do some homework because it is non-trivial. It involves things like filter-branch that I don’t have the wherewithal to cover here.

    Here are some useful resources on LFS: