add push
This commit is contained in:
@@ -596,3 +596,62 @@ The manual e2e checklist above still needs a real GRASP-06 server run.
|
||||
so a failure aborts creation cleanly with nothing announced. Two new
|
||||
`signed_git` tests (`set_origin_creates_or_replaces_the_remote`,
|
||||
`working_copy_cloned_from_the_mirror_matches_head_and_origin`).
|
||||
- **Add (after e2e, user request)** — "ready to push" watch for the
|
||||
user's own repositories: local commits made in a checkout (external
|
||||
git) surface as a **sidebar badge** on the repository row (a
|
||||
`CountBadge` with the unpushed commit count) and, when the repository
|
||||
panel is open, as an info **banner with a Push button**. The
|
||||
`CheckoutsStore` gains a second status family (`request_push_statuses`/
|
||||
`push_statuses_of`): per checked-out branch it refreshes the remote
|
||||
view (`git fetch` of the checkout's origin, offline-tolerant) and
|
||||
counts `origin/<branch>..<branch>` (`origin/HEAD` for branches the
|
||||
remote does not have yet); dirty/detached checkouts are skipped like
|
||||
the PR suggestions. Poll cadence: 15 s while a repository panel is
|
||||
open (`status_requested`), 60 s for the sidebar-only background watch;
|
||||
request sets are cleared on signer change. The repo panel's
|
||||
ready-to-contribute banner now applies only to repositories of other
|
||||
authors — owned repositories get the push banner instead, whose Push
|
||||
action calls the new `Backend::push_checkout` (shared body with the
|
||||
existing mirror-based `push_repository`): publishes a fresh 30618
|
||||
state event (keeping the announced `HEAD` branch when the checkout is
|
||||
on a side branch) then pushes every branch and tag to the announced
|
||||
grasp servers. New test
|
||||
`checkout_push_status_counts_unpushed_commits_only`. The mirror's file
|
||||
browser stays a snapshot (new commits appear after a branch switch),
|
||||
like the rest of the browser.
|
||||
- **Fix (after e2e, user report)** — a push warning "cannot lock ref
|
||||
'refs/heads/main': is at X but expected Y" (server-side compare-and-
|
||||
swap rejection, `incorrect old value provided`). Reproduced locally:
|
||||
two concurrent plain pushes of the *same* ref from the same base make
|
||||
the loser fail exactly this way — the app can race itself when two
|
||||
push sources for one repository run at once (two panels of the same
|
||||
repo, or the banner Push racing the header's Republish; each guard was
|
||||
per-view only). Fix: pushes are now single-flight per repository in
|
||||
`Backend::push_repo_from` via an `Arc<Mutex<HashSet<RepoAddr>>>` guard
|
||||
(`PushGuard`, RAII: the lock is released on completion, on error and on
|
||||
task cancellation alike); a second concurrent push fails fast with
|
||||
"A push to this repository is already in progress" instead of racing.
|
||||
Racing an external `git push` against the same server remains possible
|
||||
(benign: the ref converges; the loser logs a warning only).
|
||||
- **Fix (after e2e, user report)** — after a successful push the
|
||||
repository panel's commit list stayed on the old commit (even across
|
||||
restarts): the browser reads the GitCache mirror, and a fetch never
|
||||
moves a mirror's *local* branches — `origin/main` advanced while local
|
||||
`main` (what the commit list walks) stayed behind. ngit/nak never hit
|
||||
this because they operate on real clones the user `git pull`s; nak also
|
||||
publishes the updated 30618 state *before* each push, which Signed
|
||||
already did. Fixes, mirroring a `git pull --ff-only` on the browser
|
||||
clone: new `signed_git::fast_forward_branches(workdir)` (per local
|
||||
branch, when it is an ancestor of its `refs/remotes/origin/*`
|
||||
counterpart: the checked-out branch is merged so its worktree follows,
|
||||
dirty worktrees and local-only commits are never touched; returns
|
||||
whether anything moved); `RepoDetailView::load_repo`'s background
|
||||
refresh fast-forwards after `fetch_all` and rebuilds the explorer,
|
||||
previews and commit list (`reload_worktree`) when anything moved;
|
||||
`push_unpushed_checkout` reloads the mirror on success so an owned
|
||||
repo's pushed commit appears immediately; `ensure_origin` now also
|
||||
configures the standard `remote.origin.fetch` refspec (create-flow
|
||||
mirrors otherwise never map heads on fetch). New test
|
||||
`fast_forward_branches_moves_the_mirror_and_keeps_local_work`; the
|
||||
remote-only-branch limitation stays (a branch the mirror has never
|
||||
checked out is not listed), as documented.
|
||||
|
||||
Reference in New Issue
Block a user