feat(sync): remove the hub dependency
- add sync.go to fetch and prune the selected upstream, github, origin, or sole remote - fast-forward the current branch with merge --ff-only and inactive branches with update-ref - protect a dirty current branch and branches checked out in linked worktrees - warn without changing divergent branches - delete gone-upstream branches only after confirming they are merged into the remote default branch - allow dirty repositories by default and retain the all-clean policy behind --strict - return per-branch results in CLI, JSON, and TUI output - add bare-remote integration tests, the hub MIT notice, and version 0.3.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Stack Sync
|
||||
|
||||
`stack-sync` safely runs [`hub sync`](https://hub.github.com/hub-sync.1.html) across every Git repository in a workspace. It is designed for directory trees such as JezzWTF where the root may not be a repository and a parent repository may contain deliberately untracked, nested repositories.
|
||||
`stack-sync` safely fetches and synchronizes local branches across every Git repository in a workspace. It is designed for directory trees such as JezzWTF where the root may not be a repository and a parent repository may contain deliberately untracked, nested repositories.
|
||||
|
||||
It provides both a full-screen [Bubble Tea](https://github.com/charmbracelet/bubbletea) control deck for interactive work and a conventional CLI/JSON interface for SSH sessions and automation. Both interfaces use the same discovery and safety engine.
|
||||
|
||||
@@ -10,24 +10,24 @@ Before a repository is eligible, Stack Sync verifies that it:
|
||||
|
||||
- is on a branch (not a detached `HEAD`);
|
||||
- has at least one remote;
|
||||
- has no merge, rebase, cherry-pick, revert, or bisect in progress;
|
||||
- has no modified, staged, deleted, conflicted, or untracked files.
|
||||
- has no merge, rebase, cherry-pick, revert, or bisect in progress.
|
||||
|
||||
Untracked paths that are themselves discovered nested Git repositories are excluded from the parent repository's dirty check. All other untracked files still block it.
|
||||
Modified, staged, deleted, conflicted, and untracked files are reported but do not block the repository by default. If the checked-out branch would otherwise be fast-forwarded or deleted, Stack Sync protects that branch and continues synchronizing safe inactive branches. Branches checked out in another linked worktree are protected too. Use `--strict` when every repository must be completely clean before anything is synchronized.
|
||||
|
||||
Stack Sync never runs `git stash`, `git reset`, `git clean`, `git commit`, or any other command that saves or discards work. A repository is checked again immediately before `hub sync` to reduce the chance of a change slipping in between the plan and apply phases. Blocked repositories are skipped; use `--strict` to abort the whole run if even one is blocked.
|
||||
Untracked paths that are themselves discovered nested Git repositories are excluded from the parent repository's dirty report. All other worktree changes remain visible in the CLI, JSON, and TUI.
|
||||
|
||||
Stack Sync intentionally preserves `hub sync` semantics. That means `hub` may delete a local branch when its upstream branch has been deleted and it considers the local branch merged. It warns instead when it finds unpushed or apparently unmerged commits. The interactive confirmation calls this out; review `hub help sync` before using `--yes` in automation.
|
||||
Stack Sync never runs `git stash`, `git reset`, `git clean`, `git commit`, or any other command that saves or discards work. A repository is checked again immediately before synchronization, and the worktree is checked again before changing its checked-out branch.
|
||||
|
||||
The branch behavior is derived from the MIT-licensed `hub sync` implementation and is now built directly into Stack Sync. It fetches and prunes the main remote, fast-forwards outdated branches, warns about divergent/unpushed branches, and removes a branch only when its configured upstream was deleted and the branch is already merged into the remote default branch. It prefers a remote named `upstream`, `github`, or `origin`; a sole differently named remote is also accepted. See [third-party notices](THIRD_PARTY_NOTICES.md) for attribution.
|
||||
|
||||
## Requirements
|
||||
|
||||
Stack Sync supports Linux and Windows. It requires:
|
||||
|
||||
- Go 1.24 or newer to build;
|
||||
- Git on `PATH`;
|
||||
- [hub](https://hub.github.com/) on `PATH` for `sync` and `tui` sync operations.
|
||||
- Git on `PATH`.
|
||||
|
||||
The read-only `scan` command does not require `hub`.
|
||||
There is no separate `hub` dependency.
|
||||
|
||||
## Build and install
|
||||
|
||||
@@ -78,7 +78,7 @@ PowerShell accepts the same options with a Windows path:
|
||||
stack-sync tui --root C:\Users\you\Coding\jwtf
|
||||
```
|
||||
|
||||
Every eligible repository starts selected. Move with the arrow keys or `j`/`k`, toggle the focused repository with Space, select all with `a`, clear the selection with `n`, and refresh with `r`. Press `s` or Enter to review the destructive-branch warning, then `y` to begin. Blocked repositories cannot be selected and show their first dirty paths in the detail panel. After a run, focusing a repository shows its latest `hub` output.
|
||||
Every eligible repository starts selected. Dirty repositories remain selectable and are labelled `ready (dirty)`; their checked-out branches are protected if an update would affect them. Move with the arrow keys or `j`/`k`, toggle the focused repository with Space, select all with `a`, clear the selection with `n`, and refresh with `r`. Press `s` or Enter to review the branch-deletion warning, then `y` to begin. Blocked repositories cannot be selected. After a run, focusing a repository shows its latest per-branch results.
|
||||
|
||||
### CLI and automation
|
||||
|
||||
@@ -100,7 +100,7 @@ Review the same plan, confirm it, and sync every eligible repository:
|
||||
stack-sync sync --root ~/Coding/jwtf
|
||||
```
|
||||
|
||||
For automation, suppress the prompt and optionally require the entire workspace to be clean:
|
||||
For automation, suppress the prompt and optionally require the entire workspace to be clean. In strict mode, either a blocked repository or any worktree change aborts the whole run:
|
||||
|
||||
```bash
|
||||
stack-sync sync --root ~/Coding/jwtf --yes --strict
|
||||
@@ -110,7 +110,7 @@ Useful options:
|
||||
|
||||
```text
|
||||
--jobs 4 maximum concurrent inspections or syncs
|
||||
--timeout 5m per-repository hub sync timeout
|
||||
--timeout 5m per-repository fetch and sync timeout
|
||||
--exclude temp skip a directory name anywhere in the tree
|
||||
--exclude Org/old skip a root-relative path
|
||||
--json emit structured output
|
||||
@@ -120,4 +120,4 @@ Both `/` and `\` are accepted in Windows paths. Quote a root or exclusion contai
|
||||
|
||||
Dependency caches, build outputs, and tool-managed directories such as `node_modules`, `target`, `.claude`, and `.codex` are skipped during discovery by default. These exclusions only affect repository discovery; they never make real changes inside a discovered repository disappear from its dirty-worktree check.
|
||||
|
||||
Exit codes are `0` for a successful scan or sync (planned dirty repositories may be safely skipped), `1` for an operational/sync failure, `2` for invalid or unconfirmed non-interactive use, and `3` when strict mode refuses the plan or a previously eligible repository fails its immediate pre-sync safety check.
|
||||
Exit codes are `0` for a successful scan or sync (including protected branches and divergence warnings), `1` for an operational/sync failure, `2` for invalid or unconfirmed non-interactive use, and `3` when strict mode refuses the plan or a previously eligible repository fails its immediate pre-sync safety check.
|
||||
|
||||
Reference in New Issue
Block a user