Note: While the following worked, the entire setup felt fragile. Plus, I realized there was little point in encrypting the source code in my repository, given the repository is hosted locally on my home network where I already have encryption at rest. So, I reverted this stuff after trying it for a few days.
Initial setup
- 
Ensure the Age private key is available in the right place (i.e. ~/.config/sops/age/keys.txt). 
- 
Update .gitattributes in the repository to look something like this: # For some reason, fall back needs to be at the top. secret/* filter=sops secret/*.env filter=sops-dotenv secret/*.json filter=sops-json secret/*.yaml filter=sops-yaml secret/*.yml filter=sops-yaml
- 
Run the following in the repository: # Fallback git config --local filter.sops.clean "sops encrypt /dev/stdin" git config --local filter.sops.smudge "sops decrypt /dev/stdin" git config --local filter.sops.required true git config --local filter.sops-dotenv.clean "sops encrypt --input-type dotenv --output-type dotenv /dev/stdin" git config --local filter.sops-dotenv.smudge "sops decrypt --input-type dotenv --output-type dotenv /dev/stdin" git config --local filter.sops-dotenv.required true git config --local filter.sops-json.clean "sops encrypt --input-type json --output-type json /dev/stdin" git config --local filter.sops-json.smudge "sops decrypt --input-type json --output-type json /dev/stdin" git config --local filter.sops-json.required true git config --local filter.sops-yaml.clean "sops encrypt --input-type yaml --output-type yaml /dev/stdin" git config --local filter.sops-yaml.smudge "sops decrypt --input-type yaml --output-type yaml /dev/stdin" git config --local filter.sops-yaml.required true
On a new machine
- Again, ensure the key is present in the right place as above.
- Clone, but don’t checkout, the repository: git clone --no-checkout ...
- Apply all the config --local ...commands from above.
- Checkout: git checkout --.