be put is per-path, not aggregated (repeat banner + PUTNONE spam)
A glob (or shell-expanded multi-path) be put, e.g. be put */*/*.sh, where most matches are unchanged, emits — PER ineligible match — a fresh put: banner, a sniff: put: no eligible paths line, Error: PUTNONE, AND a redundant Error: NONE. The eligible matches DO stage; it is the unchanged ones that turn a benign "most files unchanged" put into a wall of error spam. An unchanged match in a multi-path put should be a SILENT skip, not a per-path error pair. Native be (sniff). Sibling of BE-008 (unchanged empty-put → silent no-op) and the BE-003/BE-006 error-line work. Method: Issues.
be put */*/*.sh over the beagle test dir, most .sh unchanged):
- 23:02 put put:beagle / put …/tag-blobs-from-keeper.sh (staged OK) - …/tags-from-git.sh is unchanged — skipped - sniff: put: no eligible paths / Error: PUTNONE / Error: NONE (×N)
be put be/test/bro/reentry/driver.js be/test/get/guard/guard.js → two put:be/test hunks (one file each), NOT one hunk listing both (the user ask).
be post sub-recursion: an unchanged /
empty sub-put prints put put: + Error: PUTNONE + Error: NONE per sub (seen landing this batch: subs html, beagle/abc).
sniff/PUT.c:1119-1121: `if (emitted==0){ if (skipped>0) fprintf(stderr,"sniff: put: no eligible pathsn"); return PUTNONE; }` — a put PASS that stages nothing but skipped ≥1 unchanged path returns PUTNONE + the stderr line.
sniff/PUT.c:207 / :1026 set the is unchanged skip reason; the single-file
be put file.c unchanged-skip (:987) is the intended quiet case.
so each all-unchanged pass re-emits the banner + PUTNONE (the repeated put:beagle).
Error: NONE is the dog/sniff CLI error reportersurfacing the suffix-NONE twice — the BE-003/BE-006 stacked-error class.
put: banner / HUNK per invocation listing ALL staged paths — not onebanner per path (the "must be one hunk" requirement).
be put stages the eligible matches and SILENTLY skips the
unchanged ones: NO per-match banner for a wholly-skipped match, NO per-match PUTNONE, NO Error: NONE spam.
nothing eligible (then ONE clean line, not a per-match pair).
be put file.c is unchanged skip (PUT.c:987),
the truly-empty bare put → PUTNONE (BE.cli.c), or -q swallowing *NONE (sniff/SNIFF.cli.c:193). Native sniff/keeper only; no JS.
skipped match neither prints a banner nor returns PUTNONE on its own; only the aggregate emptiness yields a single PUTNONE.
Error: NONE (fold into BE-003 uniform line).*/*/*.sh matches many files, ≤1 changed; assert
today's per-match PUTNONE/Error: NONE spam, then a single clean result. (sniff/test/refuse.sh Scenarios 5+6, test/put/01-states)
(sniff/PUT.c::put_stage_named multi = nuris > 1, PUT.c:770/1029/1074/1131)
-q quiet.
(PUT.c:1035 is unchanged kept; PUT.c:1141 aggregate summary only for nuris>1)
be internal) — the fix must handle areceived PATH LIST (shell-expanded) and an internal glob alike.
sniff/PUT.c::put_stage_named — a
multi-path/glob put (nuris>1) silently skips unchanged matches (no per-path banner / PUTNONE / no eligible paths); one-changed → ONE put: hunk. Single-file is unchanged — skipped + bare-empty PUTNONE preserved. Tests: sniff/test/refuse.sh (PUT-003 cases), test/put/01-states. beagle 464/464 + be 65/65 green. Residual (DESIGN, not a one-liner): a wholly no-op SUB still relays a banner-only put:<sub> hunk — needs a HUNKTableAbort / defer-banner / relay-filter change to the shared HUNK contract (status/get/ls). The doubled Error: NONE 2nd line is the BE-003/BE-006 error-line class.
jab log; the fix rode the
untagged 25/26Jun batch (1fd33d9f/0447e4a7 "JS-065..JS-091 … beagle"). Verified in-tree at tip b0fb0ce4: PUT.c PUT-003 comments + refuse.sh cases present, wtlog shows no pending sniff/PUT.c put row since the 26Jun get.
put:<sub> relay + PUTNONE/NONE
stderr cascade → BE-008 (open); doubled Error: NONE → BE-003/BE-006.