From 2667569a6d75b093d2af7ae9adabb23b4cd3f35d Mon Sep 17 00:00:00 2001 From: Slack Coder Date: Mon, 24 Apr 2023 10:54:14 -0500 Subject: [PATCH] cli: Fix patch open/update when out-of-sync Trying to open or update Patch will fail if the user's working copy is out of sync with the Radicle projects canonical head. Fix this by always operating on the storage when opening or updating a patch. --- radicle-cli/src/commands/patch/common.rs | 8 ++++---- radicle-cli/src/commands/patch/create.rs | 19 +++++++++---------- radicle-cli/src/commands/patch/update.rs | 16 ++++++++-------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/radicle-cli/src/commands/patch/common.rs b/radicle-cli/src/commands/patch/common.rs index 2b394e73..93572a9d 100644 --- a/radicle-cli/src/commands/patch/common.rs +++ b/radicle-cli/src/commands/patch/common.rs @@ -35,8 +35,8 @@ fn get_branch(git_ref: git::Qualified) -> git::RefString { std::iter::once(head).chain(tail).collect() } -/// Determine the merge target for this patch. This can ben any tracked remote's "default" -/// branch, as well as your own (eg. `rad/master`). +/// Determine the merge target for this patch. This can be any tracked remote's "default" branch, +/// as well as your own (eg. `rad/master`). pub fn get_merge_target( storage: &Repository, head_branch: &git::raw::Branch, @@ -170,7 +170,7 @@ pub fn find_unmerged_with_base( target_head: Oid, merge_base: Oid, patches: &Patches, - workdir: &git::raw::Repository, + storage: &Repository, whoami: &Did, ) -> anyhow::Result> { // My patches. @@ -187,7 +187,7 @@ pub fn find_unmerged_with_base( continue; } // Merge-base between the two patches. - if workdir.merge_base(**patch.head(), target_head)? == merge_base { + if storage.backend.merge_base(**patch.head(), target_head)? == merge_base { matches.push((id, patch, clock)); } } diff --git a/radicle-cli/src/commands/patch/create.rs b/radicle-cli/src/commands/patch/create.rs index 72a7fd14..c267b08d 100644 --- a/radicle-cli/src/commands/patch/create.rs +++ b/radicle-cli/src/commands/patch/create.rs @@ -26,11 +26,11 @@ and description. pub fn handle_patch_message( message: term::patch::Message, - workdir: &git::raw::Repository, + storage: &Repository, head_branch: &git::raw::Branch, ) -> anyhow::Result<(String, String)> { let head_oid = branch_oid(head_branch)?; - let head_commit = workdir.find_commit(*head_oid)?; + let head_commit = storage.backend.find_commit(*head_oid)?; let commit_message = head_commit .message() .ok_or(anyhow!("commit summary is not valid UTF-8; aborting"))?; @@ -47,7 +47,7 @@ pub fn handle_patch_message( } fn show_patch_commit_info( - workdir: &git::raw::Repository, + storage: &Repository, node_id: &NodeId, head_branch: &git::raw::Branch, target_ref: &git::RefStr, @@ -55,8 +55,8 @@ fn show_patch_commit_info( ) -> anyhow::Result<()> { let head_oid = branch_oid(head_branch)?; // The merge base is basically the commit at which the histories diverge. - let base_oid = workdir.merge_base(*target_oid, *head_oid)?; - let commits = patch_commits(workdir, &base_oid, &head_oid)?; + let base_oid = storage.backend.merge_base(*target_oid, *head_oid)?; + let commits = patch_commits(&storage.backend, &base_oid, &head_oid)?; term::info!( "{} <- {}/{} ({})", @@ -69,7 +69,7 @@ fn show_patch_commit_info( // TODO: Test case where the target branch has been re-written passed the merge-base, since the fork was created // This can also happen *after* the patch is created. - term::patch::print_commits_ahead_behind(workdir, *head_oid, *target_oid)?; + term::patch::print_commits_ahead_behind(&storage.backend, *head_oid, *target_oid)?; // List commits in patch that aren't in the target branch. term::blank(); @@ -91,7 +91,6 @@ pub fn run( let mut patches = patch::Patches::open(storage)?; let head_branch = try_branch(workdir.head()?)?; let head_branch_name = push_to_storage(workdir, storage, &head_branch, &options)?; - let (target_ref, target_oid) = get_merge_target(storage, &head_branch)?; if head_branch.upstream().is_err() { @@ -109,15 +108,15 @@ pub fn run( // base. if !quiet { - show_patch_commit_info(workdir, profile.id(), &head_branch, &target_ref, target_oid)?; + show_patch_commit_info(storage, profile.id(), &head_branch, &target_ref, target_oid)?; term::blank(); } // TODO: List matching working copy refs for all targets. - let (title, description) = handle_patch_message(message, workdir, &head_branch)?; + let (title, description) = handle_patch_message(message, storage, &head_branch)?; let head_oid = branch_oid(&head_branch)?; - let base_oid = workdir.merge_base(*target_oid, *head_oid)?; + let base_oid = storage.backend.merge_base(*target_oid, *head_oid)?; let signer = term::signer(profile)?; let patch = if draft { patches.draft( diff --git a/radicle-cli/src/commands/patch/update.rs b/radicle-cli/src/commands/patch/update.rs index 9f155735..345862af 100644 --- a/radicle-cli/src/commands/patch/update.rs +++ b/radicle-cli/src/commands/patch/update.rs @@ -16,16 +16,16 @@ blank is also okay. fn select_patch( patches: &patch::Patches, - workdir: &git::raw::Repository, + storage: &Repository, head_branch: &git::raw::Branch, target_oid: git::Oid, whoami: &Did, ) -> anyhow::Result { let head_oid = branch_oid(head_branch)?; - let base_oid = workdir.merge_base(*target_oid, *head_oid)?; + let base_oid = storage.backend.merge_base(*target_oid, *head_oid)?; let mut result = - find_unmerged_with_base(*head_oid, *target_oid, base_oid, patches, workdir, whoami)?; + find_unmerged_with_base(*head_oid, *target_oid, base_oid, patches, storage, whoami)?; let Some((id, _, _)) = result.pop() else { anyhow::bail!("No patches found to update, please specify a patch id"); @@ -40,7 +40,7 @@ fn select_patch( } fn show_update_commit_info( - workdir: &git::raw::Repository, + storage: &Repository, current_revision: &patch::Revision, head_branch: &git::raw::Branch, ) -> anyhow::Result<()> { @@ -54,7 +54,7 @@ fn show_update_commit_info( // Difference between the two revisions. let head_oid = branch_oid(head_branch)?; - term::patch::print_commits_ahead_behind(workdir, *head_oid, *current_revision.head())?; + term::patch::print_commits_ahead_behind(&storage.backend, *head_oid, *current_revision.head())?; Ok(()) } @@ -79,7 +79,7 @@ pub fn run( let patch_id = match patch_id { Some(patch_id) => patch_id, - None => select_patch(&patches, workdir, &head_branch, target_oid, &profile.did())?, + None => select_patch(&patches, storage, &head_branch, target_oid, &profile.did())?, }; let Ok(mut patch) = patches.get_mut(&patch_id) else { anyhow::bail!("Patch `{patch_id}` not found"); @@ -95,11 +95,11 @@ pub fn run( } if !quiet { - show_update_commit_info(workdir, current_revision, &head_branch)?; + show_update_commit_info(storage, current_revision, &head_branch)?; } let head_oid = branch_oid(&head_branch)?; - let base_oid = workdir.merge_base(*target_oid, *head_oid)?; + let base_oid = storage.backend.merge_base(*target_oid, *head_oid)?; let message = message.get(REVISION_MSG)?; let message = message.replace(REVISION_MSG.trim(), ""); let message = message.trim();