Bash scripts to encrypt large files with GPG before storing them in Git Large File Storage (LFS), and to decrypt them after checkout.
These scripts encrypt selected files with GPG (AES-256) so ciphertext (.gpg) can be tracked by Git LFS, and decrypt those files after clone or pull. They never default to walking the whole working tree, never store the passphrase in a shell variable, and never delete source files unless you ask.
-
Clone this repository or copy
encrypt_large_files.sh,decrypt_large_files.sh, andsecure_lfs_common.shinto the same directory. -
Make the scripts executable:
chmod +x encrypt_large_files.sh decrypt_large_files.sh
-
In the Git repository that will store the files, track ciphertext with LFS:
git lfs install git lfs track '*.gpg' git add .gitattributes
Run the scripts from inside the Git repository. PATH is required. A bare directory is not recursive; only files larger than 100MB in that directory are encrypted. Pass an explicit file to encrypt it regardless of size.
./encrypt_large_files.sh --help
./decrypt_large_files.sh --helpPreview first:
./encrypt_large_files.sh --dry-run ./artifacts
./encrypt_large_files.sh --dry-run --recursive ./artifactsEncrypt a single file, or large files in one directory:
./encrypt_large_files.sh secrets/dump.bin
./encrypt_large_files.sh ./artifactsEncrypt recursively (still skips .git), then decrypt:
./encrypt_large_files.sh --recursive ./artifacts
./decrypt_large_files.sh --recursive ./artifactsSource files are kept by default. Deletion is opt-in:
./encrypt_large_files.sh --delete-original secrets/dump.bin
./encrypt_large_files.sh --wipe-original secrets/dump.bin--wipe-original overwrites with shred before unlink. That is not reliable on SSDs or journaled filesystems.
GPG prompts for the passphrase through pinentry (and gpg-agent may cache it for later files in the same run). The scripts never read the password into a Bash variable and never pass it on the command line.
Contributions are welcome. Fork the repository, make your changes, and submit a pull request. See CONTRIBUTING.md.
MIT. Copyright © 2026 Vassbrekke AS.
Source: https://github.com/Vassbrekke/secure-git-lfs
contact@vassbrekke.no · vassbrekke.no
- 1.1.0 - 2026-08-22
- Require an explicit PATH; do not recurse from
.by default - Leave passphrase handling to GPG pinentry
- Make source deletion opt-in (
--delete-original/--wipe-original) - Add
--dry-runand refuse to encrypt unless the.gpgoutput is Git LFS-tracked
- Require an explicit PATH; do not recurse from
- 1.0.0 - 2025-07-08
- Initial release
- Pass a specific file or directory. Recursion is
--recursiveonly. - Confirm the file list with
--dry-runbefore encrypting. - Originals are not removed unless you pass
--delete-originalor--wipe-original. - Encryption is refused unless
git check-attrreportsfilter=lfsfor the.gpgoutput path. - Do not commit decrypted plaintext. Keep
.gpgas the LFS-tracked artifact. - Prefer a GPG key pair or a proper secret manager if these files are long-lived secrets rather than a shared symmetric passphrase.