Automatic backup, history tracking, and instant restore for your Home Assistant configuration.
Home Assistant Version Control provides complete version history for your setup. It automatically tracks every change to your YAML configuration files using a robust local Git backend. Browse your history, visualize diffs, and restore individual files or your entire configuration to any previous state with a single click.
- Cloud Backup: Push your configuration to a private GitHub or Gitea repository. Choose to sync manually, daily, or automatically after every change.
- Track More than Just YAML: Now you can select any file format to track and backup! Configure extensions like .sh, .py, .json directly in the add-on's Configuration tab.
- Recover Deleted Items: View and restore files, automations, and scripts that have been deleted. Look for the "Deleted" option in the sort menu.
- Progressive History Loading: Versions now load faster, displaying results as they're found.
- Quick Style Toggle: Tap the header bar of any file diff to instantly cycle through different visual styles (High Contrast, GitHub Classic, Neon, etc.).
- Zero-Effort Backups: Every edit is saved automatically.
- Smart Debouncing: Multiple rapid edits are grouped into a single save snapshot (customizable delay).
- Comprehensive Tracking: Monitors
.yaml,.yml, andlovelacedashboard files (both UI and YAML mode). - Efficient Storage: Uses Git deduplication to minimize disk usage by storing only the differences between versions.
- Chronological Feed: View changes grouped by "Today," "Yesterday," and "Earlier."
- Visual Comparisons: Compare the current version against any backup side-by-side. Additions are highlighted in green, deletions in red.
- History Management: Automatically merges versions older than the specified time period to keep your history clean.
- Granular Control: Restore specific files or revert your entire configuration.
- Smart Reloads: Automatically reloads Home Assistant when restoring automation or script files to apply changes immediately.
- Instant Rollback: Long-press the restore button to revert the entire system to a previous point in time.
- Color Theme: Choose from seven preset color palettes.
- Light Themes: Toggle between Light and Dark modes.
- Comparison View:
- Style: Customize your comparisons with 8 different themes (High Contrast, GitHub Classic, Neon, etc.).
- Layout: Choose between Stacked (Unified) or Side-by-Side views.
- Comparison:
- Current (Default): Compare against your Current File on disk to see how far you've deviated since that backup.
- Changes: Compare against the Previous Version to see exactly what changed in that specific backup.
- Restore Single File: Click the "Restore" button on any file in the timeline.
- Restore All Files: Long-press (2 seconds) the "Restore" button on a timeline entry to revert all tracked files to that exact moment.
- Timeline Context Menu: Right-click on any version in the timeline to access:
- Reset Timeline Here: Remove all versions newer than the selected point (keeps your files unchanged, only cleans up timeline history).
- Restore All Files Here: Revert all tracked files back to their state at the selected version.
Important
- Existing Git Repos: If you already have a
.gitfolder in your/configdirectory, back it up first. The add-on will use your existing repository but may conflict with your workflow through auto-commits and automatic merging of old history. For best results, delete the existing.gitfolder and let the add-on create a fresh repository. - Backup Strategy: While this add-on provides excellent version control, do not rely on it as your sole backup method. Always maintain external backups (e.g., Google Drive, Samba) of your Home Assistant instance.
There are two ways to install Home Assistant Version Control: as a Home Assistant add-on or as a standalone Docker container.
-
Add Repository: Click the button below to add the repository to your Home Assistant instance:
Or manually add it:
- Navigate to Settings → Add-ons → Add-on Store
- Click the three dots (⋮) in the top right corner and select Repositories
- Add the repository URL:
https://github.com/saihgupr/ha-addons
-
Install the Add-on: The "Home Assistant Version Control" add-on will now appear in the store. Click on it and then click "Install".
-
Start: Start the add-on and click "Open Web UI" to access the interface.
-
Optional (External Access): To access the UI externally at port
54001, enable the port in the add-on's Configuration tab (disabled by default).
For Docker users who aren't using the Home Assistant add-on, you have three deployment options:
Option A: Docker Compose (recommended):
-
Download the compose.yaml file:
curl -o compose.yaml https://github.com/saihgupr/HomeAssistantVersionControl/raw/develop/compose.yaml
-
Edit the file to set your paths and timezone:
nano compose.yaml # Update the volume path: /path/to/your/ha/config # Update timezone: TZ environment variable (e.g., America/New_York)
-
Start the service:
docker compose up -d
Access the interface at http://localhost:54001.
Option B: Docker Run (pre-built image):
docker run -d \
-p 54001:54001 \
-v /path/to/your/config:/config \
-e TZ=America/New_York \
-e SUPERVISOR_TOKEN=your_long_lived_access_token_here \
-e HA_URL=http://homeassistant.local:8123 \
--name home-assistant-version-control \
ghcr.io/saihgupr/home-assistant-version-control:latestReplace /path/to/your/config with the actual path to your Home Assistant configuration directory.
Option C: Build locally:
git clone https://github.com/saihgupr/HomeAssistantVersionControl.git
cd HomeAssistantVersionControl/homeassistant-version-control
docker build --build-arg BUILD_FROM=alpine:latest -t home-assistant-version-control .
docker run -d \
-p 54001:54001 \
-v /path/to/your/config:/config \
-e TZ=America/New_York \
-e SUPERVISOR_TOKEN=your_long_lived_access_token_here \
-e HA_URL=http://homeassistant.local:8123 \
--name home-assistant-version-control \
home-assistant-version-controlNote
The SUPERVISOR_TOKEN and HA_URL are optional. You can omit those lines if you don't need Home Assistant restart/reload features.
Access the interface at http://localhost:54001.
The application can be configured through the web UI Settings page or via environment variables for containerized deployments.
| Setting | Description | Default |
|---|---|---|
| Debounce Time | Time to wait after detecting changes before creating a commit | 5 seconds |
| History Retention | Automatically merge old commits to keep history clean | Disabled |
| Retention Type | Keep history based on time or number of versions | time |
| Retention Value | How much history to keep (number of days/hours/weeks/months or versions) | 90 |
| Retention Unit | Time unit for retention (hours, days, weeks, months) | days |
For containerized deployments (especially when not persisting the /data directory), you can configure runtime settings using environment variables. This is particularly useful for:
- Docker/Podman deployments without persistent data volumes
- Infrastructure-as-code configurations
- Automated deployments with predefined settings
Precedence order (per-setting):
- Settings file (
/data/runtime-settings.json) - highest priority - Environment variables - middle priority
- Default values - fallback
| Environment Variable | Setting | Type | Valid Values | Default |
|---|---|---|---|---|
DEBOUNCE_TIME |
Debounce Time | Number | ≥ 0 | 5 |
DEBOUNCE_TIME_UNIT |
Debounce Time Unit | String | seconds, minutes, hours, days |
seconds |
HISTORY_RETENTION |
History Retention | Boolean | true, false, yes, no, 1, 0 |
false |
RETENTION_TYPE |
Retention Type | String | time, versions |
time |
RETENTION_VALUE |
Retention Value | Number | ≥ 1 | 90 |
RETENTION_UNIT |
Retention Unit | String | hours, days, weeks, months |
days |
Notes:
- Boolean values are case-insensitive and accept:
true/false,yes/no,1/0 - String values (units, types) are case-insensitive:
SECONDSandsecondsare equivalent - Invalid values trigger warnings in logs and fall back to defaults
- Empty values are ignored
Docker Compose with environment variables:
version: '3.8'
services:
havc:
image: ghcr.io/saihgupr/home-assistant-version-control:latest
ports:
- "54001:54001"
volumes:
- /path/to/your/config:/config
environment:
- TZ=America/New_York
- DEBOUNCE_TIME=10
- DEBOUNCE_TIME_UNIT=minutes
- HISTORY_RETENTION=true
- RETENTION_TYPE=time
- RETENTION_VALUE=30
- RETENTION_UNIT=daysDocker Run with environment variables:
docker run -d \
-p 54001:54001 \
-v /path/to/your/config:/config \
-e TZ=America/New_York \
-e DEBOUNCE_TIME=10 \
-e DEBOUNCE_TIME_UNIT=minutes \
-e HISTORY_RETENTION=true \
-e RETENTION_TYPE=time \
-e RETENTION_VALUE=30 \
-e RETENTION_UNIT=days \
--name home-assistant-version-control \
ghcr.io/saihgupr/home-assistant-version-control:latestValidation and Logging:
When the container starts, you'll see detailed logging showing where each setting value came from:
[init] Runtime settings loaded:
[init] debounceTime: 10 (env: DEBOUNCE_TIME)
[init] debounceTimeUnit: 'minutes' (env: DEBOUNCE_TIME_UNIT)
[init] historyRetention: true (env: HISTORY_RETENTION)
[init] retentionType: 'time' (default)
[init] retentionValue: 30 (env: RETENTION_VALUE)
[init] retentionUnit: 'days' (default)
Invalid values will trigger warnings:
[init] Warning: Invalid DEBOUNCE_TIME='abc', Expected integer, got: 'abc'. Using default: 5
- File Watcher: The system continuously monitors your
/configfolder for changes to YAML files. - Stabilization: When a change is detected, it waits 2 seconds to ensure Home Assistant has finished writing the file (preventing corruption).
- Debounce: It then waits for your configured Debounce Time (default 5s) to batch related edits into a single commit.
- Snapshot: A Git commit is created with a timestamp.
- Cleanup: If enabled, old snapshots are consolidated periodically.
The add-on automatically tracks configuration files while ignoring system files.
| Tracked ✅ | Ignored ❌ |
|---|---|
configuration.yaml |
Database files (.db, .db-shm) |
automations.yaml, scripts.yaml |
Log files (*.log) |
secrets.yaml |
Python cache (__pycache__) |
Lovelace dashboards (.storage/lovelace*) |
Binary files (Images, Videos) |
esphome/*.yaml |
Temporary files |
All other .yaml and .yml files |
Files in .gitignore |
Caution
Secrets Management & Cloud Backup:
By default, secrets.yaml is excluded from version control to protect sensitive information like passwords and API keys. If you use the Cloud Backup feature and choose to include secrets.yaml, ensure your remote repository is private and understand that secrets will be stored in Git history. Consider using Home Assistant's built-in secrets management or environment variables for sensitive data instead.
Tip
Excluding Files:
You can prevent specific files from being tracked by adding them to a .gitignore file in your /config directory. Just list the filenames (one per line) that you want to exclude, and the add-on will automatically ignore them from version control.
You can automatically sync your configuration to a private remote repository. This is highly recommended for off-site backups.
If you are using a custom Git server like Gitea, follow these steps to ensure a smooth sync (note: this is not required for standard GitHub setups):
- Create a Private Repository: Log in to your Git server and manually create a private repository named
VersionControlBackupbefore attempting to sync from the UI. - Authentication URL: Use the following URL format in the Cloud Sync settings, substituting your token, IP/domain, and username:
http://YOUR_API_TOKEN@YOUR_SERVER_IP:PORT/YOUR_USERNAME/VersionControlBackup.git
API for advanced users or automation.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/git/add-all-and-commit |
Manual Backup: Forces a commit of all current changes. |
POST |
/api/run-retention |
Run Cleanup: Manually triggers the history retention cleanup process. |
POST |
/api/retention/cleanup |
Advanced Cleanup: Run cleanup with custom time parameters. |
POST |
/api/restore-commit |
Time Travel: Restore ALL files to a specific point in time. |
POST |
/api/restore-file |
Restore File: Restore a single file to a specific commit. |
POST |
/api/git/hard-reset |
Hard Reset: Reset the repository to a specific commit (destructive). |
POST |
/api/ha/restart |
Restart HA: Triggers a Home Assistant restart. |
GET |
/api/git/history |
Get History: Returns the full commit history log. |
GET |
/api/git/file-diff |
File Comparison: Get the diff for a specific file in a commit. |
GET |
/api/git/commit-diff |
Commit Comparison: Get the full diff for a specific commit. |
Reset the repository to a specific commit. WARNING: This is destructive and will discard all changes since that commit.
Parameters:
commitHash(string, required): The full or short hash of the commit to reset to.createBackup(boolean, optional): Iftrue, creates a safety backup commit of the current state before resetting. Default:false.
Example:
{
"commitHash": "a1b2c3d4",
"createBackup": true
}Restore all files to their state at a specific commit. This creates a new commit on top of the current history, preserving history.
Parameters:
commitHash(string, required): The hash of the commit to restore.
Example:
{
"commitHash": "e5f6g7h8"
}Restore a single file to its state at a specific commit.
Parameters:
commitHash(string, required): The hash of the commit containing the version of the file you want.filePath(string, required): The relative path to the file (e.g.,automations.yaml).
Example:
{
"commitHash": "i9j0k1l2",
"filePath": "scripts.yaml"
}Run the history retention cleanup process with custom parameters.
Parameters:
days(number, optional): Keep history for the last N days.hours(number, optional): Keep history for the last N hours.minutes(number, optional): Keep history for the last N minutes.months(number, optional): Keep history for the last N months.
Example:
curl -X POST http://homeassistant.local:54001/api/retention/cleanup \
-H "Content-Type: application/json" \
-d '{"hours": 24}'Found a bug? Feel free to open an issue.
Want to contribute? Check out CONTRIBUTING.md for guidelines.
Want the latest features? The develop branch includes the most recent updates and features.
If you find this project useful, please consider giving it a star, or buy me a coffee if you'd like!



