Clean workspace (make it match the depot)

- Actions -> Clean workspace: preview extra/deleted/modified files, then apply
  p4 clean (opened files untouched)
- Backend p4 clean -n / clean

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bonchellon
2026-07-08 12:06:11 +03:00
parent ecc5b8e9bf
commit 28a3989095
4 changed files with 89 additions and 1 deletions

View File

@ -1867,6 +1867,31 @@ async fn p4_latest_change(state: State<'_, AppState>, scope: String) -> Result<V
Ok(v.into_iter().next().unwrap_or(Value::Null))
}
/// Preview `p4 clean` — files that would be deleted (local extras), restored
/// (locally deleted) or refreshed (locally modified but not opened) to make the
/// workspace exactly match the depot. Non-destructive (`-n`).
#[tauri::command]
async fn p4_clean_preview(state: State<'_, AppState>, scope: String) -> Result<Vec<Value>, String> {
let conn = current(&state)?;
run_json(&conn, &["clean", "-n", &scope_spec(&scope)]).or_else(|e| {
let l = e.to_lowercase();
if l.contains("no file") || l.contains("up-to-date") || l.contains("no such") || l.contains("no differing") {
Ok(Vec::new())
} else {
Err(e)
}
})
}
/// Apply `p4 clean`: make the workspace match the depot, discarding un-opened
/// local edits/adds/deletes. Streams progress.
#[tauri::command]
async fn p4_clean_apply(state: State<'_, AppState>, scope: String) -> Result<String, String> {
let conn = current(&state)?;
let msg = run_stream(&conn, &["clean", &scope_spec(&scope)], "sync")?;
Ok(if msg.is_empty() { "Workspace already matches the depot.".into() } else { msg })
}
/// Full revision history of a single file (`p4 filelog -l`), including
/// per-revision changelist, action, user, time and description. Returns the
/// tagged object with rev0/change0/action0/… arrays.
@ -2223,6 +2248,8 @@ pub fn run() {
p4_switch_stream,
p4_stream_integ,
p4_filelog,
p4_clean_preview,
p4_clean_apply,
p4_jobs,
p4_fix,
p4_job_spec,