Using Git LFS
Note
Examples use CLI v2.
This topic is written for release maintainers and describes how to set up Git LFS for storing release blobs and final releases as an alternative to S3 or other external blobstores.
Overview¶
Git LFS (Large File Storage) allows you to manage release blobs alongside your release code in the same Git repository. Instead of distributing separate credentials for blob uploads, contributors use standard Git credentials. This simplifies access management and enables external contributors to bump dependencies without requiring separate blobstore access.
Prerequisites¶
- Git LFS client: Install Git LFS on your machine. Follow the official installation instructions.
- Git server with LFS support: Ensure your Git hosting provider supports Git LFS (GitHub, GitLab, Gitea, Bitbucket, etc.).
- Understanding of LFS storage: Be aware that your Git hosting provider may have storage and bandwidth quotas for LFS objects. Review their pricing and limits.
Trade-offs¶
Advantages¶
- No separate credentials needed: Uses standard Git credentials instead of requiring
config/private.ymlwith blobstore access keys. - Simplified contributor workflow: External contributors can add and update blobs using standard Git operations without needing special blobstore access.
- Access control via Git: Permissions are managed through your Git repository access model (teams, branches, etc.).
- Enterprise-friendly: Works in environments where obtaining public-facing S3 buckets is difficult or impossible.
Disadvantages¶
- Higher cost: Git LFS is typically more expensive per GB than S3.
- Storage and bandwidth quotas: Most Git hosting providers impose limits on LFS storage and bandwidth, which may require paid plans for large releases.
- Performance: Very large blob files may be slower to download via Git LFS compared to S3.
- Repository size: Git LFS objects are stored in your repository history, which can impact repository clone times.
Decision Matrix¶
| Scenario | Use Git LFS | Use S3 | Rationale |
|---|---|---|---|
| Internal release, small team | ✓ | - | Simpler access management via Git |
| Public open-source release | - | ✓ | S3 is more cost-effective for public distribution |
| Large blobs (>100MB each) | - | ✓ | S3 performs better for very large files |
| Enterprise, no public S3 allowed | ✓ | - | Git LFS works behind firewalls |
| External contributors need write access | ✓ | - | Avoids distributing blobstore credentials |
| Cost-sensitive | - | ✓ | S3 is cheaper for large-scale storage |
Setup¶
1. Initialize Git LFS in Your Release Repository¶
Follow the Git LFS getting started guide to initialize Git LFS in your release repository:
cd my-release
git lfs install
2. Track Blob Directories with Git LFS¶
Use git lfs track to configure .gitattributes for your blob directories:
git lfs track "blobs/**" git lfs track "final_blobs/**"
This creates/updates your .gitattributes file with the appropriate Git LFS filter configuration.
Commit the .gitattributes file:
git add .gitattributes
git commit -m "Configure Git LFS for release blobs"
3. Configure config/final.yml¶
Update config/final.yml to use the local provider with final_blobs directory:
--- name: my-release blobstore: provider: local options: blobstore_path: final_blobs
Commit this configuration:
git add config/final.yml
git commit -m "Configure local blobstore with final_blobs directory"
4. Ensure .gitignore is Correct¶
Your .gitignore should include:
blobs/* !blobs/.gitkeep
This ensures the blobs/ directory exists but blob files are not tracked by Git (Git LFS handles them via .gitattributes). The blobs/ directory contains local blob staging and should not be committed.
The final_blobs/ directory should NOT be in .gitignore because Git LFS-tracked files must be committed to Git.
Developer Workflow¶
Adding a Blob¶
- Add the blob to your release:
bosh add-blob ~/Downloads/some-package-1.0.0.tar.gz some-package-1.0.0.tar.gz
The bosh add-blob command copies the file to blobs/ and updates config/blobs.yml.
- Commit to Git:
git add config/blobs.yml
git commit -m "Add some-package 1.0.0 blob"
Git LFS automatically tracks the blob file via .gitattributes patterns.
Creating a Final Release¶
- Create the final release:
bosh create-release --final
This generates the final release tarball and places it in the final_blobs/ directory.
- Commit to Git:
git add config/blobs.yml config/index.yml final_blobs/
git commit -m "Finalize release v1.0.0"
git tag v1.0.0
The final_blobs/ directory contents are automatically tracked by Git LFS via .gitattributes.
For Contributors¶
External contributors follow the same workflow:
- Clone the repository (Git LFS objects are downloaded automatically):
git clone https://github.com/your-org/my-release.git
- Add or update blobs:
bosh add-blob ~/Downloads/new-dependency-2.0.0.tar.gz new-dependency-2.0.0.tar.gz
git add config/blobs.yml
git commit -m "Bump new-dependency to 2.0.0"
- Push the changes (including LFS objects):
git push
No special credentials or access to a separate blobstore are required.
Cloning a Release with Git LFS¶
When cloning a repository with Git LFS blobs, Git LFS automatically downloads all blob objects. For detailed information on cloning and pulling with Git LFS, see the Git LFS documentation.
git clone https://github.com/your-org/my-release.git
cd my-release
If LFS objects fail to download, you can manually pull them:
git lfs pull
Migrating from S3 to Git LFS¶
If you're migrating an existing release from S3 to Git LFS:
- Set up Git LFS in your repository as described in the Setup section above.
- Download blobs from your current S3 blobstore.
- Use
bosh add-blobto add each blob to your release. - Commit the blobs and updated
config/blobs.ymlto Git (Git LFS automatically tracks them via.gitattributes). - Update
config/final.ymlto point tofinal_blobswith the local provider.
Refer to the Git LFS documentation for details on working with large files and repositories.
Troubleshooting¶
For Git LFS-specific troubleshooting (installation, authentication, object downloading), refer to the Git LFS documentation.
Large Repository Size¶
If your repository becomes too large, consider:
- Archiving old final releases into separate branches
- Pruning old LFS objects (carefully, as this affects rebuild ability from older commits)
- Using shallow clones for development: git clone --depth 1
LFS Quota Issues¶
If you hit Git hosting provider LFS quota limits: - Review and optimize blob sizes - Consider moving large static assets to S3 and having Git LFS track only references - Upgrade to a higher storage tier on your Git hosting provider
BOSH-Specific Issues¶
If bosh add-blob doesn't work as expected with Git LFS, ensure:
- .gitattributes is properly configured with the patterns shown in the Setup section
- You are committing the blobs to Git (Git LFS tracks them automatically via .gitattributes)
- Your .gitignore allows final_blobs/ directory to be committed
When to Use Git LFS¶
Use Git LFS for your release blobstore if:
- Your release team is internal or a controlled group where Git access management is sufficient
- You work in an enterprise environment where obtaining public-facing S3 buckets is difficult
- You want to simplify contributor workflow by avoiding separate blobstore credentials
- You can accept higher costs and potential storage/bandwidth quotas in exchange for simpler access management
- Your blobs are reasonably sized (< 100MB each for best performance)
Consider S3 or another external blobstore if:
- Your release is public and you need cost-effective, high-performance distribution
- You have very large blobs or high bandwidth requirements
- Cost is a primary concern
- You need fine-grained access control independent of Git repository access