Integrate / Merge / Copy between branches

- Tools -> Integrate / Merge / Copy: pick op + source/target paths, runs into a
  new pending changelist; resolve (if needed) via the Resolve UI and submit
- Backend p4 merge/copy/integrate -c

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bonchellon
2026-07-08 11:53:12 +03:00
parent 2811aec6e8
commit fdaf126c00
4 changed files with 86 additions and 1 deletions

View File

@ -1783,6 +1783,28 @@ async fn p4_resolve_file(state: State<'_, AppState>, file: String, mode: String)
}
}
/// Propagate changes between branches/streams: op is "merge" (with resolve),
/// "copy" (overwrite target), or "integrate" (classic). Opens the affected files
/// into a fresh numbered changelist; the user then resolves (if needed) and
/// submits via the normal pending-changelist flow. Returns the changelist number.
#[tauri::command]
async fn p4_branch_op(state: State<'_, AppState>, op: String, source: String, target: String) -> Result<String, String> {
let conn = current(&state)?;
let cmd = match op.as_str() {
"merge" => "merge",
"copy" => "copy",
_ => "integrate",
};
let src = source.trim();
let tgt = target.trim();
if src.is_empty() || tgt.is_empty() {
return Err("Source and target paths are required".into());
}
let cl = create_changelist(&conn, &format!("{cmd} {src} -> {tgt}"))?;
let out = run_text(&conn, &[cmd, "-c", &cl, src, tgt]).unwrap_or_default();
Ok(format!("CL {cl}\n{}", out.trim()))
}
/// Unified diff between two exact revisions (`p4 diff2 -du`).
#[tauri::command]
async fn p4_diff2(state: State<'_, AppState>, spec1: String, spec2: String) -> Result<String, String> {
@ -2084,6 +2106,7 @@ pub fn run() {
p4_sync_to,
p4_labels,
p4_label_tag,
p4_branch_op,
p4_client_spec,
p4_client_save,
uasset_thumbnail,