Synchronize Git repositories between dom0, a dedicated SyncVM, and GitHub in Qubes OS.
This script enables you to keep full Git history while respecting Qubes’ strict isolation model:
- dom0: edit files, stage, and commit (but never connect to the network).
- SyncVM: acts as a proxy — it receives commit bundles from dom0 and pushes them to GitHub.
- GitHub: stores your full repository history.
To stay reasonable secure: Please review and understand what the script does before adding it to your own qubes installation (as with every other piece of code you get from the internet ;-)
Qubes OS intentionally disconnects dom0 from the network for security.
That means you cannot git push from dom0 directly.
This script provides a secure workflow:
- Keep real Git history in dom0.
- Use
git bundleto export commits from dom0. - Transfer the bundle to SyncVM via
qvm-run --pass-io. - SyncVM imports the commits and pushes to GitHub.
- Optionally, SyncVM can pull updates from GitHub and copy them back to dom0.
-
Copy the script into dom0:
sudo install -m 755 qubes-git-sync /usr/local/bin/qubes-git-sync
-
Adjust these variables in the script if needed:
SYNCVM="my-git-sync"→ name of your dedicated AppVM that has network access to GitHub.GITHUB_USER="your-github-username"→ your GitHub username.ALL_REPOS="my-qubes another-repo scripts-docs"→ list of repositories managed by--all.
-
In your SyncVM:
- Configure SSH access to GitHub (e.g. deploy your SSH keys).
- Ensure
gitis installed.
-
Make sure that user.email and user.name for git commits are setup correctly in the SyncVM an dom0! This is required so that pushing commits will work. To do so run the following commands:
git config --global user.name 'NAME'git config --global user.email 'EMAIL'
-
In dom0
- Edit your files as usual.
- Stage and commit changes:
git add file1 file2 git commit -m "Describe your changes"
-
Sync changes to GitHub
qubes-git-sync gitpush <repository>
This will:
- Create a
git bundlein dom0. - Transfer it securely to your SyncVM.
- Import the bundle and push commits to GitHub.
- Create a
-
Pull updates from GitHub into dom0
qubes-git-sync gitpull <repository>
This will:
git pullin SyncVM from GitHub.- Copy the updated repository tree back to dom0.
Push one repository:
qubes-git-sync gitpush my-qubesPush all repositories defined in ALL_REPOS:
qubes-git-sync gitpush --allPull latest changes from GitHub into dom0:
qubes-git-sync gitpull my-qubesAll actions are logged in dom0 at:
~/.qubes-git-sync.log
- dom0 never connects to the network; only SyncVM interacts with GitHub.
- Only committed changes are synchronized. Uncommitted edits in dom0 will not be included.
- Temporary bundle files are removed after each sync (both in dom0 and SyncVM).
- Only the
mainbranch is synchronized. - Merge conflicts are not automatically resolved — the script enforces fast-forward merges only.
- If you forget to commit in dom0 before running
gitpush, no changes will be transferred.
GPLv3 License – see LICENSE file for details.
👉 With this setup, you can safely manage your configuration and documentation repos in dom0 while still keeping them synchronized with GitHub.