feat(push): refspec syntax local:remote for cross-branch pushes (muse#43)
Phases 1-3 of muse#43: - New parse_push_refspec(raw) -> (local_branch, remote_branch, force) in push.py. Parses git-style [+]<local>[:<remote>] syntax: a bare name keeps the existing single-name behavior (local == remote), "local:remote" decouples which local branch is read from which remote branch is advanced, and a leading "+" sets force for that one push. Empty local or remote side, or more than one ':', raises ValueError before any network call -- delete-by-refspec (":remote") is deliberately unsupported, since `muse push --delete <remote> <branch>` already covers that explicitly. - Wired into run(): local_branch drives every purely-local read (get_head_commit_id, read_reflog); remote_branch drives every remote- facing operation (remote_branch_heads lookups, get_remote_head/ set_remote_head, the unpack-mpack target, and the JSON `branch` field, which per the ticket always reflects the branch actually updated on the remote). --delete's branch argument is intentionally left unparsed -- deleting "dev:main" has no sensible meaning. - docs/agent-guide.md: new "refspec syntax for cross-branch pushes" section with the four canonical forms, plus a Gitism Glossary entry clarifying that push --json's `branch` field means the remote branch (relevant once local != remote), and a second entry noting refspec syntax now matches git exactly (a reassurance, not a gotcha). `muse agent-config sync` reports zero drift.
21 new tests in tests/test_push_refspec.py (RS_01-RS_10): 8 pure-function unit tests for parse_push_refspec, 5 integration tests driving the full mocked mpack-presign/PUT/unpack-mpack protocol through muse push <remote> <refspec> --json. Confirmed via genuine RED (reverted the run() wiring, kept parse_push_refspec itself since Phase 1 is independently unit-tested) -> all 5 integration tests failed with an uncaught validate_branch_name exception (proving the wiring, not just the parser, is load-bearing) -> GREEN.
Live-verified end-to-end against a real local musehub server (localhost:1337): created a disposable test repo, confirmed `muse push testremote dev:main` from the main branch advances remote main to local dev's tip without switching branches, confirmed remote never gained a "dev" branch, and confirmed `muse push testremote +dev:main` force-pushes past a diverged remote main with force=true correctly reaching the server. Test repo deleted after verification.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
55 symbols
Files Changed
+1
~2
1250 in snapshot
0 comments
muse hub commit comment sha256:1c3d22f581aa652cf47f38f4dc32816f888bffc5fa53b579dc6f139f333a6090 --body "your comment"
No comments yet. Be the first to start the discussion.