TUI for managing git-backed configuration backups on CachyOS/Arch
Project description
git-back-dots
Git-backed configuration backups for CachyOS and Arch Linux.
git-back-dots discovers configuration files, groups them by package or
component, and manages git repos with a Textual terminal UI. It has a headless
runner for systemd timers, path triggers, and shutdown commits.
Discovery, the git runner, logging, scheduling, environment-token detection, snapshot repositories, package-config suggestions, workarounds, OAuth device-flow login, and the core TUI all work and are covered by tests. The provider-side remote-creation flow and branch-merge UI are not finished yet.
Repository modes
inplace — the git root contains the tracked files. /etc is the canonical
example: gbd run etc commits changes directly inside /etc. Use this for
system configuration trees.
snapshot — a managed repo stores copies of scattered source files under a
deterministic files/… tree. Before every commit the runner syncs each tracked
source into the snapshot; restore copies back atomically. Use this for
dotfiles and package configs that live anywhere on disk.
gbd repo add dots ~/.local/share/git-back-dots/dots --mode snapshot \
--track ~/.config/fish/config.fish --track ~/.bashrc
gbd run dots --mode commit
gbd repo restore dots ~/.config/fish/config.fish
Install
From PyPI (recommended):
uv tool install git-back-dots
That installs gbd and git-back-dots into uv's tool bin directory
(~/.local/bin by default — make sure it is on your PATH).
For the checkout being developed here:
cd ~/Projects/etc/20260725/git-back-dots
uv tool install --editable .
For an unreleased GitHub checkout:
uv tool install git+https://github.com/boundring/git-back-dots.git
Requirements
- Linux with systemd (timers/path units are how scheduled runs fire)
- git, and an SSH key or PAT for pushing to remotes
- CachyOS/Arch for the pacman-aware
scan packages/repo suggestfeatures; everything else is distribution-agnostic
Shell completion and man page
gbd --install-completion # completion for bash/zsh/fish
gbd man --install ~/.local/share/man/man1 # then: man gbd
gbd man with no options prints the manual to the terminal. gbd --help
and gbd COMMAND --help cover every subcommand.
Commands
gbd # launch the TUI
gbd doctor # git, systemd, ssh-key, PAT, and registry checks
gbd scan etc # discover /etc candidates and package owners
gbd scan home # discover dotfiles and ~/.config candidates
gbd scan packages # pacman-aware config suggestions per naming schema
gbd repo suggest # turn package suggestions into snapshot repos
gbd auth env # detect GITHUB_TOKEN, GH_TOKEN, CODEBERG_TOKEN
gbd auth ssh # list public keys and test provider SSH auth
gbd auth login github # OAuth device-flow login (needs --client-id or env)
gbd man # print the manual; --install DIR installs gbd.1
gbd repo list # show registered repositories
gbd run NAME --mode push
gbd workaround add NAME --target PATH # track a live patch
gbd workaround check # drift report (exit 1 when stale)
gbd workaround apply NAME # re-apply now
gbd run is the command generated systemd units execute. It commits only when
the repo is dirty, then pushes with BatchMode SSH and hard timeouts.
Repository naming schema
| Prefix | Scope | Use |
|---|---|---|
dots-<pkg> |
user | dotfiles owned by a package |
etc-<pkg> |
system | package-owned system configuration |
etc-base |
system | the whole /etc tree (inplace) |
wa-<name> |
any | workaround repos (see below) |
Workarounds
A workaround is a live patch applied to another tool's files — for example a
hotfix inside an installed application that its next update will clobber.
git-back-dots tracks the patched files in a dedicated snapshot repo under
~/.local/share/git-back-dots/workarounds/<name>/, generates an idempotent
apply.sh, and can re-apply automatically:
gbd workaround add my-fix --target ~/.local/lib/tool/patched.py
gbd workaround schedule my-fix # path unit watches the live file
The path unit fires when the target changes. The runner then checks drift:
if the live file differs from the snapshot (the update clobbered the patch),
apply.sh installs the tracked copy back before committing — the repo always
records the patched state. Your own edits are safe: the runner syncs them
into the snapshot on the same pass, so intentional changes are committed, not
reverted. Disable with --no-auto and apply manually with
gbd workaround apply NAME.
apply.sh runs as the installing user (via sudo -E for --system
workarounds). It is generated from the repo and committed to git history —
review it like any other privileged script. Keep workaround repos private if
the patched files come from proprietary or third-party source.
Packages
gbd scan packages combines a well-known profile list (Emacs, KDE/Plasma,
fish, common AI CLIs, …) with an /etc sweep over everything pacman has
installed. Library, framework, and game packages are filtered out by default;
--all shows them dimmed, and ignore_packages in the config extends the
filter. AI-CLI profiles are explicit allowlists — auth tokens, session
databases, and history files are never tracked, and the pre-commit secret
scanner is the backstop.
gbd repo suggest --apply registers the suggestions as snapshot repos using
the naming schema above.
Authentication
Authentication sources are resolved in this order:
- SSH remotes and local SSH authentication.
- Provider PATs in the current process environment.
- Tokens stored through the system keyring, falling back to an owner-only file.
GitHub environment variables: GITHUB_TOKEN, then GH_TOKEN.
Codeberg environment variables: CODEBERG_TOKEN, then GITEA_TOKEN.
OAuth device flow
gbd auth login github (or codeberg) walks the OAuth device flow: it
prints a one-time code and verification URL, polls until you authorize,
validates the token, stores it via the system keyring (or an owner-only file),
and registers the account. The TUI Accounts screen offers the same flow on
l. The device flow needs a public OAuth app client ID — register an OAuth
app with the provider (device flow enabled), then pass --client-id or set
GBD_GITHUB_CLIENT_ID / GBD_CODEBERG_CLIENT_ID.
gbd auth env masks token values and only prints the final four characters.
Tokens are never put in a remote URL or written to the run journal.
System services do not inherit your login environment. For root-owned
repos, use a root-owned SSH key and SSH remote. The system registry is copied
to /etc/git-back-dots/config.toml during schedule installation; it contains
repo metadata only, never PAT values.
Scheduling model
Per repo, git-back-dots generates:
- a delayed boot/interval timer that runs
pushafter networking is available; - an optional
PathChanged=unit for selected hot files; - a shutdown service that performs a local commit only.
The shutdown unit never attempts a network push. A later timer or the next boot sends the committed change. Pushes use a 15-second limit and SSH batch mode, so they cannot request a password or hang indefinitely.
Validate the generated units before installing them:
gbd schedule install NAME
systemctl --user list-timers 'gbd-*' # user repos
systemctl list-timers 'gbd-*' # system repos
journalctl -t git-back-dots
Current limits
- A timer can fire while a file is mid-edit; git commits whatever bytes are on disk. Inherent to any file-based backup — prefer quiescent times (boot, shutdown, idle intervals) for system repos.
- OAuth device-flow login is wired (
gbd auth login, TUIl). It stores tokens and registers accounts, but it does not yet create provider-side remotes for you — create the empty repo on GitHub/Codeberg yourself, thengbd repo add NAME PATH --remote URL. HTTPS credential injection for git pushes is also not wired — use SSH remotes or env-var PATs for pushing. - The TUI includes dashboard, discovery, repo files/history/schedule views, accounts, logs, notifications, workarounds, and a per-file history browser with restore-from-any-version. Branch merge UI is still planned.
Development
uv sync --extra dev
uv run ruff check src/ tests/
uv run pytest tests/ -q
uv build
License
GPL-3.0-only. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file git_back_dots-0.2.1.tar.gz.
File metadata
- Download URL: git_back_dots-0.2.1.tar.gz
- Upload date:
- Size: 57.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f334c4853e9d3f5d6f2bba81faf590a48c3e4f790538cbfd4ee04f506ef2156
|
|
| MD5 |
43e07d34aff0ecadac0de62512d60d65
|
|
| BLAKE2b-256 |
5ae013270acb5688a4d556e91ad0ddffae6ddb00106e3f1a3c0d95844b341e75
|
File details
Details for the file git_back_dots-0.2.1-py3-none-any.whl.
File metadata
- Download URL: git_back_dots-0.2.1-py3-none-any.whl
- Upload date:
- Size: 74.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33d908ca2a69b4afa5e7ffcd1cdc0fc12c812a8e03518a4636af40104a16ec89
|
|
| MD5 |
356a05b1357beb24e8214c9931899d0d
|
|
| BLAKE2b-256 |
589def67b0f976707fae3e3988bed49ddbf412224a84a7f71308c3d905ad3c91
|