(
repository: Arc<RepositoryContext>,
token: RepositoryWriteToken,
message: String,
layer_path: String,
keys: LoreArray<LoreString>,
values: LoreArray<LoreString>,
formats:
| 606 | /// live in `.urc/layer.toml`, not in the parent's revision tree. |
| 607 | #[allow(clippy::too_many_arguments)] |
| 608 | async fn commit_layer_only( |
| 609 | repository: Arc<RepositoryContext>, |
| 610 | token: RepositoryWriteToken, |
| 611 | message: String, |
| 612 | layer_path: String, |
| 613 | keys: LoreArray<LoreString>, |
| 614 | values: LoreArray<LoreString>, |
| 615 | formats: LoreArray<LoreMetadataType>, |
| 616 | stats: bool, |
| 617 | ) -> Result<Hash, CommitError> { |
| 618 | // Resolve the layer by target_path against the parent's configured layers. |
| 619 | // Unlike the auto-bundle path (which falls back to "no layers" on error), |
| 620 | // a scoped commit must surface config-read failures so the user knows |
| 621 | // their explicit `--layer <path>` request couldn't be evaluated. |
| 622 | let layers = layer::list(repository.clone()) |
| 623 | .await |
| 624 | .forward::<CommitError>("Failed to load layer configuration")?; |
| 625 | let layer = layers |
| 626 | .into_iter() |
| 627 | .find(|l| l.target_path == layer_path) |
| 628 | .ok_or_else(|| -> CommitError { |
| 629 | NotALayer { |
| 630 | path: layer_path.clone(), |
| 631 | } |
| 632 | .into() |
| 633 | })?; |
| 634 | |
| 635 | let layer_repository_ctx = Arc::new(repository.to_layer_context(layer.repository).await); |
| 636 | let layer_state = layer |
| 637 | .deserialize_current_and_staged(layer_repository_ctx.clone()) |
| 638 | .await |
| 639 | .forward::<CommitError>("Failed to deserialize layer states")?; |
| 640 | |
| 641 | let context = execution_context(); |
| 642 | let globals = context.globals(); |
| 643 | |
| 644 | // Match auto-bundle semantics: zero-staged unconditionally errors (nothing |
| 645 | // to commit, force can't help), staged-matches-current errors unless |
| 646 | // `--force` is set. |
| 647 | if layer.staged.is_zero() || (!globals.force() && layer.staged == layer.current) { |
| 648 | return Err(NothingStaged.into()); |
| 649 | } |
| 650 | |
| 651 | let (_parent_current_revision, parent_current_branch) = |
| 652 | crate::instance::load_current_anchor(&repository) |
| 653 | .await |
| 654 | .forward::<CommitError>("Failed to deserialize current revision anchor")?; |
| 655 | |
| 656 | // Detect concurrent advancement of the layer's branch by another instance. |
| 657 | // Mirrors the auto-bundle parent's branch-advanced check — if the layer's |
| 658 | // branch latest pointer has moved past `layer.current`, the staged state |
| 659 | // would create a divergent revision unless `--force` is set. |
| 660 | let layer_branch = layer_state |
| 661 | .state_current |
| 662 | .branch(layer_state.repository.clone()) |
| 663 | .await; |
| 664 | let layer_branch_latest = branch::load_latest(layer_state.repository.clone(), layer_branch) |
| 665 | .await |
no test coverage detected