Sync tracked environment files through a private Git repository.
gitenv keeps environment files out of your project repository while still making them portable across machines. It stores the synced files in a separate sync repository, then applies pull/push plans between your project directory and that sync repository.
Developers often:
- accidentally commit
.envfiles - lose environment variables
- duplicate configs across machines
gitenv solves this by:
- storing your env files in a separate private repo
- syncing them via simple commands
- keeping your main repo clean and safe
- Profile-based sync configuration.
- Profile inheritance with
extends. - Pull and push plans before disk writes.
- Dry-run mode for previewing changes without applying them.
- Optional plan rendering.
- Gitignore safety check for tracked files.
- Conflict protection when pulling into project files.
- Optional deletion of project files missing from the sync repository.
npm install -g @yukiakai/gitenvCreate a configuration file and ensure init-time gitignore entries:
gitenv init --repository <private-repository-url> --project <project-name>Example:
gitenv init \
--repository git@github.com:you/private-env.git \
--project my-appOptions:
-r, --repository <repository> private repository URL
-p, --project <projectName> project name used as the sync repository branch
-C, --cwd <workingDirectory> working directory, defaults to .
-f, --force overwrite existing configuration
gitenv.config.json contains profiles. A profile defines which files are tracked and which files are ignored while resolving tracked files.
{
"default": {
"repo": "git@github.com:you/private-env.git",
"projectName": "my-app",
"tracked": [".env", ".env.local"],
"ignore": [],
"extends": []
},
"api": {
"extends": ["default"],
"tracked": ["apps/api/.env"]
}
}extends lets a profile inherit configuration from other profiles. The selected profile is resolved before sync workflows are created.
Pull tracked files from the sync repository into the project:
gitenv pull --profile defaultOptions:
-p, --profile <profileName> profile name
-c, --config <configurationFile> configuration file path
--dry-run build the sync plan without writing changes to disk
--quiet-plan do not render sync plan
--delete-missing delete project files missing from the sync repository
--overwrite-conflicts overwrite conflicting project files
--allow-unignored allow tracked files not covered by .gitignore
Pull behavior:
- Files present only in the sync repository are created in the project.
- Files present on both sides are updated from the sync repository.
- Files present only in the project are kept unless
--delete-missingis used. - Project file content conflicts are rejected unless
--overwrite-conflictsis used.
Push tracked files from the project into the sync repository:
gitenv push --profile default --message "update env"Options:
-p, --profile <profileName> profile name
-m, --message <commitMessage> commit message
-c, --config <configurationFile> configuration file path
--dry-run build the sync plan without writing changes to disk
--quiet-plan do not render sync plan
--allow-unignored allow tracked files not covered by .gitignore
Push behavior:
- Files present only in the project are created in the sync repository.
- Files present on both sides update the sync repository.
- Files present only in the sync repository are deleted.
- After applying changes to
.gitenv/repo, gitenv commits and pushes the sync repository.
By default, tracked files must be covered by the project .gitignore. This helps prevent environment files from being committed to the project repository.
Use this only when you intentionally want to bypass that safety check:
gitenv push --profile default --message "update env" --allow-unignoredgitenv also ignores its own application state directory while resolving tracked files, so broad patterns like **/* do not sync .gitenv.
Use --dry-run to build and render the sync plan without writing files:
gitenv pull --profile default --dry-run
gitenv push --profile default --message "update env" --dry-runUse --quiet-plan when you do not want the plan rendered:
gitenv pull --profile default --dry-run --quiet-planPush before moving to another machine:
gitenv push --profile default --message "update env"Pull on the other machine:
gitenv pull --profile defaultMIT Yuki Akai