forge::merge (crates/knotless/src/forge.rs) sends the target update and, unless kept, the spent head branch's delete in one push (push_as, around line 1011). Through a gateway, pushRefs (crates/knotless-serve/src/gateway.rs around 382-400) checks each update against the branch rules, pushes the allowed ones and reports the refused ones beside them. So when the head branch is protected, the target moves and the delete is refused. accepted() (forge.rs ~1413) then bails on the refused delete, before the merged state is written: the commit is on the branch, the pull reads open, and its closing keywords close nothing.
The merge queue's landing has the same shape.
Possible fixes: leave a branch the rules protect out of spent(), or write the merged state whenever the target update landed and report the refused delete as a warning.
forge::merge(crates/knotless/src/forge.rs) sends the target update and, unless kept, the spent head branch's delete in one push (push_as, around line 1011). Through a gateway,pushRefs(crates/knotless-serve/src/gateway.rs around 382-400) checks each update against the branch rules, pushes the allowed ones and reports the refused ones beside them. So when the head branch is protected, the target moves and the delete is refused.accepted()(forge.rs ~1413) then bails on the refused delete, before themergedstate is written: the commit is on the branch, the pull reads open, and its closing keywords close nothing.The merge queue's landing has the same shape.
Possible fixes: leave a branch the rules protect out of
spent(), or write themergedstate whenever the target update landed and report the refused delete as a warning.Verified by reading the code; not reproduced.