Skip to main content

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 suggest features; 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:

  1. SSH remotes and local SSH authentication.
  2. Provider PATs in the current process environment.
  3. 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 push after 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, TUI l). 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, then gbd 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

git_back_dots-0.2.1.tar.gz (57.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

git_back_dots-0.2.1-py3-none-any.whl (74.4 kB view details)

Uploaded Python 3

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

Hashes for git_back_dots-0.2.1.tar.gz
Algorithm Hash digest
SHA256 9f334c4853e9d3f5d6f2bba81faf590a48c3e4f790538cbfd4ee04f506ef2156
MD5 43e07d34aff0ecadac0de62512d60d65
BLAKE2b-256 5ae013270acb5688a4d556e91ad0ddffae6ddb00106e3f1a3c0d95844b341e75

See more details on using hashes here.

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

Hashes for git_back_dots-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 33d908ca2a69b4afa5e7ffcd1cdc0fc12c812a8e03518a4636af40104a16ec89
MD5 356a05b1357beb24e8214c9931899d0d
BLAKE2b-256 589def67b0f976707fae3e3988bed49ddbf412224a84a7f71308c3d905ad3c91

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page