Acquire the repo-scoped shadow-commit lock, or return `None` (a no-op skip) if a shadow materialize/commit is already in flight (SPEC §4.3 / Principle 5). Non-blocking: rather than queueing (which would hang a turn-end hook), the contended case is a logged no-op — the in-flight operation owns this commit. The returned guard must be held for the whole stage → validate → commit sequence; dropping i
(
repo: &Repository,
repo_root: &Path,
view: &str,
)
| 109 | /// sequence; dropping it releases the lock. Acquire it **outermost**, before any |
| 110 | /// staging or DB write. |
| 111 | pub(crate) fn acquire_shadow_lock( |
| 112 | repo: &Repository, |
| 113 | repo_root: &Path, |
| 114 | view: &str, |
| 115 | ) -> CliResult<Option<std::fs::File>> { |
| 116 | match repo |
| 117 | .try_lock_shadow_commit() |
| 118 | .map_err(CliError::Repository)? |
| 119 | { |
| 120 | Some(guard) => Ok(Some(guard)), |
| 121 | None => { |
| 122 | if std::io::stderr().is_terminal() { |
| 123 | print_info("Another shadow materialize is in flight; skipping this push."); |
| 124 | } else { |
| 125 | append_shadow_log( |
| 126 | repo_root, |
| 127 | "shadow-lock:contended", |
| 128 | view, |
| 129 | "another shadow materialize in flight", |
| 130 | ); |
| 131 | } |
| 132 | Ok(None) |
| 133 | } |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | /// Stage the current working copy for a shadow commit, run the pre-commit |
| 138 | /// Validator, and return the candidate git tree OID. |
no test coverage detected