|
| 1 | +# git-auto-sync |
| 2 | + |
| 3 | +Monitor multiple local Git repositories on a schedule, automatically pick files to commit, generate a commit message, push changes, and notify via your chosen channels. |
| 4 | + |
| 5 | +It is inspired by a single-repo bash script but redesigned for multi-repo workflows with a configuration-driven model, platform-native scheduling, and pluggable AI and notifier providers. |
| 6 | + |
| 7 | +## Workflow |
| 8 | + |
| 9 | +For each configured repository: |
| 10 | + |
| 11 | +1. Skip with no output when there are no changes |
| 12 | +2. **Smart staging**: let AI review changed files and select commit candidates, excluding secrets, build artifacts, and large files. Excluded files can be auto-added to `.gitignore` (if AI is unavailable, it falls back to `git add -A`). |
| 13 | +3. AI generates a Conventional Commits message. |
| 14 | +4. `git commit` |
| 15 | +5. `git pull --rebase` → `git push` (on conflict, abort cleanly, mark as failed, continue with the next repo). |
| 16 | +6. Summarize and notify by strategy. |
| 17 | + |
| 18 | +## Installation |
| 19 | + |
| 20 | +### One-line install (recommended) |
| 21 | + |
| 22 | +macOS / Linux: |
| 23 | + |
| 24 | +```bash |
| 25 | +curl -fsSL https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.sh | bash |
| 26 | +``` |
| 27 | + |
| 28 | +Windows PowerShell: |
| 29 | + |
| 30 | +```powershell |
| 31 | +powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.ps1 | iex" |
| 32 | +``` |
| 33 | + |
| 34 | +It installs automatically: installs [uv](https://docs.astral.sh/uv/) when missing, downloads the latest release to `~/.git-auto-sync`, runs `uv sync`, and places a global `git-auto-sync` launcher in `~/.local/bin` (shell script on macOS/Linux, `.cmd` on Windows). The first run starts `init`. Re-running updates the existing installation; existing config is preserved by default. Use `GIT_AUTO_SYNC_VERSION=v0.1.0` for a pinned version and `GIT_AUTO_SYNC_DIR` to change install path. |
| 35 | + |
| 36 | +> Non-interactive installs (`--yes`) write the config and skip scheduler setup, then run `init` so a repository does not become automatically scheduled until you explicitly run `git-auto-sync install`. |
| 37 | +
|
| 38 | +### Manual install |
| 39 | + |
| 40 | +```bash |
| 41 | +cd git-auto-sync |
| 42 | +uv sync # Install dependencies |
| 43 | +uv run git-auto-sync init # Run the setup wizard (see below) |
| 44 | +# Or install as a CLI command: |
| 45 | +uv tool install . |
| 46 | +``` |
| 47 | + |
| 48 | +### Setup wizard (`init`) |
| 49 | + |
| 50 | +```bash |
| 51 | +git-auto-sync init # Interactive: scan directories, choose repos, pick AI provider, configure notifiers, and optionally install scheduler |
| 52 | +git-auto-sync init --yes # Non-interactive with defaults; scheduler is not installed |
| 53 | +``` |
| 54 | + |
| 55 | +The wizard scans up to two levels deep from the parent directory (`~/programming` by default) and lets you pick repositories; you can also add paths manually. After writing `~/.git-auto-sync/config.toml`, it validates immediately. |
| 56 | + |
| 57 | +### Update |
| 58 | + |
| 59 | +```bash |
| 60 | +git-auto-sync update # Download latest release and run uv sync (launcher path remains stable, scheduler is not reinstalled) |
| 61 | +git-auto-sync update --check # Check for updates only |
| 62 | +``` |
| 63 | + |
| 64 | +## Configuration |
| 65 | + |
| 66 | +Default config path is `~/.git-auto-sync/config.toml` (override with `--config`). Runtime files (config, logs, scheduler artifacts) are stored in `~/.git-auto-sync/`. |
| 67 | + |
| 68 | +```bash |
| 69 | +mkdir -p ~/.git-auto-sync |
| 70 | +cp config.example.toml ~/.git-auto-sync/config.toml |
| 71 | +``` |
| 72 | + |
| 73 | +See [`config.example.toml`](config.example.toml) for all fields. |
| 74 | + |
| 75 | +- `[defaults]` provides global defaults, and each `[[repos]]` can override fields. |
| 76 | +- String values can use `env:VARNAME` and are resolved from environment variables at runtime. |
| 77 | +- `ai_provider`: `claude-cli` (default, uses local `claude` CLI) / `anthropic-api` (reads `ANTHROPIC_API_KEY`) / `rules` (rule-based fallback). If any AI provider fails, the flow automatically falls back to rule mode. |
| 78 | +- `notify_on`: `change_or_fail` (default, changed or failed only), `fail_only`, or `always`. |
| 79 | + |
| 80 | +## Commands |
| 81 | + |
| 82 | +```bash |
| 83 | +git-auto-sync init # Run setup wizard and create config |
| 84 | +git-auto-sync sync # Sync all repositories |
| 85 | +git-auto-sync sync --repo foo # Sync only repos matching path foo |
| 86 | +git-auto-sync sync --dry-run # Show candidates without changing anything |
| 87 | +git-auto-sync status # Show branches and clean/dirty state per repo |
| 88 | +git-auto-sync config check # Validate config file |
| 89 | +git-auto-sync install --interval 30m # Install platform-native scheduler |
| 90 | +git-auto-sync uninstall # Remove scheduler integration |
| 91 | +git-auto-sync update # Self-update to latest release |
| 92 | +``` |
| 93 | + |
| 94 | +Exit codes: `0` = success, `1` = at least one repository failed, `2` = `--repo` matched no repository. |
| 95 | + |
| 96 | +## Scheduling |
| 97 | + |
| 98 | +`install` creates and enables a platform-native scheduler and does not run a resident process: |
| 99 | + |
| 100 | +- **macOS** → launchd(`~/Library/LaunchAgents/com.octopusgarage.git-auto-sync.plist`) |
| 101 | +- **Linux** → systemd user timer(`~/.config/systemd/user/git-auto-sync.timer`) |
| 102 | +- **Windows** → Task Scheduler(`OctopusGarage.git-auto-sync`) |
| 103 | + |
| 104 | +Intervals support `30m` / `1h` / `90s`. Uninstall with `git-auto-sync uninstall`. |
| 105 | + |
| 106 | +## Notifiers |
| 107 | + |
| 108 | +- `log`: append timestamped blocks to log file and print to stdout (audit friendly) |
| 109 | +- `telegram`: bot token + chat_id |
| 110 | +- `lark`: Feishu custom robot webhook |
| 111 | + |
| 112 | +After each sync, a summary is sent through all enabled notifiers according to `notify_on`. Failure in one notifier does not affect others or the main sync flow. |
| 113 | + |
| 114 | +## Safety boundaries |
| 115 | + |
| 116 | +The biggest risk in unattended automation is committing bad content. This tool defends with: |
| 117 | + |
| 118 | +- AI staging excludes secrets, credentials, certificates, `node_modules`/`dist`/`build`/`__pycache__`, large binaries, logs, and other non-source artifacts. |
| 119 | +- Excluded files are **never committed** and are written into `.gitignore` when `ai_gitignore_autowrite=true`. |
| 120 | +- When uncertain, run `--dry-run` first to preview. |
| 121 | + |
| 122 | +## Development |
| 123 | + |
| 124 | +```bash |
| 125 | +uv run pytest # Run tests |
| 126 | +uv run ruff check . # Run linting |
| 127 | +``` |
| 128 | + |
| 129 | +## Release |
| 130 | + |
| 131 | +Use the assistant command: |
| 132 | + |
| 133 | +- `.claude/commands/release.md` contains the full release flow used in this repo: |
| 134 | + - preflight checks (`pytest`, `ruff`) |
| 135 | + - version bump (`pyproject.toml` + `uv.lock`) |
| 136 | + - release publish on GitHub |
| 137 | + - install/update validation |
| 138 | + |
| 139 | +For manual release scripts, run the version bump and release flow in that file. |
| 140 | + |
| 141 | +## License |
| 142 | + |
| 143 | +MIT |
0 commit comments