Skip to main content

Git repository synchronization tool

Project description

twshtd

Git repository synchronization tool for managing multiple repositories.

Installation

# Install with uv
uv tool install twshtd

# Or install from source
uv tool install -e .

Usage

twshtd [OPTIONS] COMMAND [ARGS]

Commands

Command Description
push Commit and push all configured repositories
pull Commit local changes and pull from remotes
info Show configuration and repository status
edit Open configuration file in $EDITOR
dirty Show dirty/behind/ahead status for repos in directories

Options

Option Description
-v, --verbose Enable debug logging
-V, --version Show version

Push Command

twshtd push [OPTIONS]

Commits all changes and pushes to remote for each configured repository.

Option Description
-c, --config Config file path
-w, --workers Parallel workers (number or 'auto')
-n, --dry-run Show what would be done

Pull Command

twshtd pull [OPTIONS]

Commits local changes and pulls from remotes. Supports two modes per repository:

  • pull: Full git pull (default)
  • fetch: Only fetch, showing what changed
Option Description
-c, --config Config file path
-w, --workers Parallel workers (number or 'auto')
-n, --dry-run Show what would be done

Dirty Command

twshtd dirty [OPTIONS]

Scans configured directories for git repositories and shows their status.

Option Description
-c, --config Config file path
--no-fetch Skip git fetch before checking status

Configuration

Config file location (in order of precedence):

  1. TWSHTD_CONFIG environment variable
  2. ~/.config/twshtd/repos.toml

Example Configuration

[settings]
workers = 1  # parallel workers (1 = sequential)

# Global hooks - run before/after ALL repos
pre_commands = [
    "! pgrep -x anki",  # Block push if Anki is running
]
post_commands = []

[[repos]]
path = "~/dev/project1"
pull_mode = "pull"                    # "pull" or "fetch"
pre_commands = ["make clean"]         # run before push (all must pass)
post_commands = ["make build"]        # run after pull (warn on failure)
enabled = true

[[repos]]
path = "$PROJECTS/project2"
pull_mode = "fetch"
pre_commands = ["git stash list"]     # multiple commands supported
post_commands = ["make test", "make lint"]

[[repos]]
path = "~/dev/disabled-repo"
enabled = false

# Directories to scan with 'dirty' command
[[dirty]]
path = "~/dev"
enabled = true

[[dirty]]
path = "$WORK/repos"

Path Resolution

Paths support:

  • Home directory expansion (~)
  • Environment variables ($VAR or ${VAR})

Features

Hooks (Pre-Commands / Post-Commands)

Hooks allow you to run shell commands at specific points in the workflow.

Global Hooks

Define in [settings] to run for ALL repos:

[settings]
pre_commands = ["! pgrep -x anki"]  # Block if Anki running
post_commands = ["echo 'All done'"]
  • pre_commands: Run once before processing any repos. ALL must succeed (exit 0) or the entire operation stops.
  • post_commands: Run once after all repos are processed. Failures show warnings but don't fail the operation.

Per-Repo Hooks

Define per repository for repo-specific actions:

[[repos]]
path = "~/dev/myproject"
pre_commands = ["make clean", "npm ci"]  # before push
post_commands = ["make build", "make test"]  # after pull
  • pre_commands: Run before push. ALL must succeed or the repo is skipped (other repos continue).
  • post_commands: Run after pull. Failures show warnings but the repo is marked as successful.

Commands run in the repository directory (per-repo) or current directory (global).

Execution Order

PUSH:
1. Global pre_commands (all must pass, or exit 1)
2. For each repo:
   a. Repo pre_commands (all must pass, or skip this repo)
   b. Git commit + push
3. Global post_commands (warn on failure)

PULL:
1. Global pre_commands (all must pass, or exit 1)
2. For each repo:
   a. Git pull/fetch
   b. Repo post_commands (warn on failure)
3. Global post_commands (warn on failure)

Commit Message

When committing changes, twshtd uses git status --porcelain output as the commit message, providing a clear record of what changed.

Example: Blocking Push if Anki Running

To prevent pushing when Anki is running (e.g., to avoid sync conflicts with Anki repos), use a global pre_command:

[settings]
pre_commands = ["! pgrep -x anki"]

This command exits 1 (failure) if Anki is running, blocking the push.

rplc Integration

For repositories using rplc, twshtd automatically swaps out files before committing. Use --skip-rplc to bypass.

Development

# Install dev dependencies
uv sync

# Run tests
make test

# Lint and format
make static-analysis

License

MIT

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

twshtd-1.1.1.tar.gz (14.4 kB view details)

Uploaded Source

Built Distribution

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

twshtd-1.1.1-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file twshtd-1.1.1.tar.gz.

File metadata

  • Download URL: twshtd-1.1.1.tar.gz
  • Upload date:
  • Size: 14.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for twshtd-1.1.1.tar.gz
Algorithm Hash digest
SHA256 ccdf632bc2cf126e127c4c88eecdea346ee679bd605e315f02419cf25d27d85f
MD5 32744b7f138c1c82c73400a0cf2ab520
BLAKE2b-256 bfcf3ddf7d663ba60d99a5057479e82f81074323bea70dd54196298c053df268

See more details on using hashes here.

File details

Details for the file twshtd-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: twshtd-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for twshtd-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1118814afbac8ed0f2187277502248f92289a833b1e9d99f186bc386eb8bf28b
MD5 86e83bd96ed89a7250158e28fad4d26a
BLAKE2b-256 d60e2f3cff307b5efa7d48ee1c003022404ab2f96335db123876bc2bc7b62356

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