A couple of weeks ago we started to use Github’s Large File Storage extension for git. That was a real challenge and now I want to share some tips and tricks with you.
1. Get rid of
git lfs install
git lfs install does actually two things:
- Adds pre-push hook to the repository, preventing you from pushing when LFS client is not installed
- Adds some configurations to
Add LFS client’s configurations to your global
git config --global filter.lfs.required true git config --global filter.lfs.clean "git-lfs clean -- %f" git config --global filter.lfs.smudge "git-lfs smudge -- %f" git config --global filter.lfs.process "git-lfs filter-process"
You won’t have to initialize LFS every time you clone a repository.
Change your remotes’ protocols to
ssh, so you will not need to use git’s credential-cache.
Otherwise, you have to type login and password for every file you download from the GH media server.
3. It takes long time to fetch
LFS has the batch mode for downloading files from a server. But it does not work on clone and checkout due to limitation of git’s smudge filters. You can skip LFS’s smudge filter and fetch LFS objects on demand. For that:
1. Change the smudge filter configuration:
git config --global filter.lfs.smudge "git-lfs smudge --skip %f" git config --global filter.lfs.process "git-lfs filter-process --skip"
git lfs env and be sure that the smudge filter is skipped.
2. Fetch LFS objects after checkout or clone:
git lfs fetch # downloads objects with batch mode git lfs checkout # changes objects to binary files
4. Commited binary file, can not rebase, checkout or hard reset
You’ve got a trouble if someone commits binary file and pushes it to remote. After rebase from remote everybody will have that file on stage, it cannot be removed or resetted.
Pre-push hook provided by Github will not save you. It will check whether LFS client is installed or not, exactly that. You could commit a binary file and install LFS client just before pushing.
As a workaround, you can:
- Revert commit with binary file
- Remove LFS client configurations from
.gitconfig. It can be checked easily by
git lfs env
- Get configurations back to
Since that solution won’t prevent this problem in the future we wrote a pre-commit hook:
#!/usr/bin/env bash set -e BINARY_FILES="" CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACM) LFS_FILES=$(echo $CHANGED_FILES | xargs git check-attr filter | grep 'filter: lfs$' | sed -e 's/: filter: lfs//') for FILE in $LFS_FILES; do SOFT_SHA=$(git hash-object -w $FILE) RAW_SHA=$(git hash-object -w --no-filters $FILE) if [ $SOFT_SHA == $RAW_SHA ]; then BINARY_FILES="$FILE\n$BINARY_FILES" fi done if [[ -n "$BINARY_FILES" ]]; then echo "Attention!" echo "----------" echo "You tried to commit binary files:" echo -e "\x1B[31m$BINARY_FILES\x1B[0m" echo "Revert your changes and commit those files with git-lfs!" echo "----------" exit 1 fi
But you can’t commit changes in the .git folder, for that purpose we use small, but powerful
manager git-hooks-js. Simply, you can save a hook to
provide it to team members. For more information see documentation.
And remember, your friends are:
git lfs env GIT_TRACE=1 git lfs <cmd> git lfs logs last