Submit options (-r / revert-unchanged / -e shelved) + .p4ignore editor

- Pending changelist menu: Submit & keep checked out (-r), Submit reverting
  unchanged, Submit shelved (-e)
- Tools -> Edit .p4ignore: read/write workspace .p4ignore with an Unreal template
- Backend p4 submit -r/-f revertunchanged/-e, .p4ignore read/write

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

View File

@ -600,6 +600,57 @@ async fn p4_submit_change(state: State<'_, AppState>, change: String) -> Result<
run_stream(&conn, &["submit", "-c", &change], "submit")
}
/// Submit a shelved changelist directly from the server (`submit -e`), without
/// needing the files in the workspace.
#[tauri::command]
async fn p4_submit_shelved(state: State<'_, AppState>, change: String) -> Result<String, String> {
let conn = current(&state)?;
run_stream(&conn, &["submit", "-e", change.trim()], "submit")
}
/// Submit a numbered changelist with options: `reopen` keeps the files checked
/// out after submit (`-r`); `revert_unchanged` drops files with no real change
/// (`-f revertunchanged`).
#[tauri::command]
async fn p4_submit_opts(state: State<'_, AppState>, change: String, reopen: bool, revert_unchanged: bool) -> Result<String, String> {
let conn = current(&state)?;
let ch = change.trim().to_string();
let mut args: Vec<String> = vec!["submit".into(), "-c".into(), ch];
if reopen {
args.push("-r".into());
}
if revert_unchanged {
args.push("-f".into());
args.push("revertunchanged".into());
}
let refs: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
run_stream(&conn, &refs, "submit")
}
/// Path of the workspace `.p4ignore` file (at the client root).
fn ignore_path(conn: &Conn) -> Option<std::path::PathBuf> {
if conn.root.is_empty() {
return None;
}
Some(std::path::Path::new(&conn.root).join(".p4ignore"))
}
/// Read the workspace `.p4ignore` (empty string if none yet).
#[tauri::command]
async fn p4_ignore_read(state: State<'_, AppState>) -> Result<String, String> {
let conn = current(&state)?;
let p = ignore_path(&conn).ok_or("No workspace root known")?;
Ok(std::fs::read_to_string(&p).unwrap_or_default())
}
/// Write the workspace `.p4ignore`.
#[tauri::command]
async fn p4_ignore_write(state: State<'_, AppState>, content: String) -> Result<(), String> {
let conn = current(&state)?;
let p = ignore_path(&conn).ok_or("No workspace root known")?;
std::fs::write(&p, content).map_err(|e| format!("Could not write .p4ignore: {e}"))
}
/// "Uncommit": move files back into the default changelist (like `git reset`).
/// The now-empty numbered changelist is cleaned up on the next `p4_changes`.
#[tauri::command]
@ -2250,6 +2301,10 @@ pub fn run() {
p4_filelog,
p4_clean_preview,
p4_clean_apply,
p4_submit_shelved,
p4_submit_opts,
p4_ignore_read,
p4_ignore_write,
p4_jobs,
p4_fix,
p4_job_spec,