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.
This commit is contained in:
parent
e757750398
commit
2667569a6d
|
|
@ -35,8 +35,8 @@ fn get_branch(git_ref: git::Qualified) -> git::RefString {
|
||||||
std::iter::once(head).chain(tail).collect()
|
std::iter::once(head).chain(tail).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine the merge target for this patch. This can ben any tracked remote's "default"
|
/// Determine the merge target for this patch. This can be any tracked remote's "default" branch,
|
||||||
/// branch, as well as your own (eg. `rad/master`).
|
/// as well as your own (eg. `rad/master`).
|
||||||
pub fn get_merge_target(
|
pub fn get_merge_target(
|
||||||
storage: &Repository,
|
storage: &Repository,
|
||||||
head_branch: &git::raw::Branch,
|
head_branch: &git::raw::Branch,
|
||||||
|
|
@ -170,7 +170,7 @@ pub fn find_unmerged_with_base(
|
||||||
target_head: Oid,
|
target_head: Oid,
|
||||||
merge_base: Oid,
|
merge_base: Oid,
|
||||||
patches: &Patches,
|
patches: &Patches,
|
||||||
workdir: &git::raw::Repository,
|
storage: &Repository,
|
||||||
whoami: &Did,
|
whoami: &Did,
|
||||||
) -> anyhow::Result<Vec<(PatchId, Patch, Clock)>> {
|
) -> anyhow::Result<Vec<(PatchId, Patch, Clock)>> {
|
||||||
// My patches.
|
// My patches.
|
||||||
|
|
@ -187,7 +187,7 @@ pub fn find_unmerged_with_base(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Merge-base between the two patches.
|
// 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));
|
matches.push((id, patch, clock));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@ and description.
|
||||||
|
|
||||||
pub fn handle_patch_message(
|
pub fn handle_patch_message(
|
||||||
message: term::patch::Message,
|
message: term::patch::Message,
|
||||||
workdir: &git::raw::Repository,
|
storage: &Repository,
|
||||||
head_branch: &git::raw::Branch,
|
head_branch: &git::raw::Branch,
|
||||||
) -> anyhow::Result<(String, String)> {
|
) -> anyhow::Result<(String, String)> {
|
||||||
let head_oid = branch_oid(head_branch)?;
|
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
|
let commit_message = head_commit
|
||||||
.message()
|
.message()
|
||||||
.ok_or(anyhow!("commit summary is not valid UTF-8; aborting"))?;
|
.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(
|
fn show_patch_commit_info(
|
||||||
workdir: &git::raw::Repository,
|
storage: &Repository,
|
||||||
node_id: &NodeId,
|
node_id: &NodeId,
|
||||||
head_branch: &git::raw::Branch,
|
head_branch: &git::raw::Branch,
|
||||||
target_ref: &git::RefStr,
|
target_ref: &git::RefStr,
|
||||||
|
|
@ -55,8 +55,8 @@ fn show_patch_commit_info(
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let head_oid = branch_oid(head_branch)?;
|
let head_oid = branch_oid(head_branch)?;
|
||||||
// The merge base is basically the commit at which the histories diverge.
|
// The merge base is basically the commit at which the histories diverge.
|
||||||
let base_oid = workdir.merge_base(*target_oid, *head_oid)?;
|
let base_oid = storage.backend.merge_base(*target_oid, *head_oid)?;
|
||||||
let commits = patch_commits(workdir, &base_oid, &head_oid)?;
|
let commits = patch_commits(&storage.backend, &base_oid, &head_oid)?;
|
||||||
|
|
||||||
term::info!(
|
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
|
// 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.
|
// 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.
|
// List commits in patch that aren't in the target branch.
|
||||||
term::blank();
|
term::blank();
|
||||||
|
|
@ -91,7 +91,6 @@ pub fn run(
|
||||||
let mut patches = patch::Patches::open(storage)?;
|
let mut patches = patch::Patches::open(storage)?;
|
||||||
let head_branch = try_branch(workdir.head()?)?;
|
let head_branch = try_branch(workdir.head()?)?;
|
||||||
let head_branch_name = push_to_storage(workdir, storage, &head_branch, &options)?;
|
let head_branch_name = push_to_storage(workdir, storage, &head_branch, &options)?;
|
||||||
|
|
||||||
let (target_ref, target_oid) = get_merge_target(storage, &head_branch)?;
|
let (target_ref, target_oid) = get_merge_target(storage, &head_branch)?;
|
||||||
|
|
||||||
if head_branch.upstream().is_err() {
|
if head_branch.upstream().is_err() {
|
||||||
|
|
@ -109,15 +108,15 @@ pub fn run(
|
||||||
// base.
|
// base.
|
||||||
|
|
||||||
if !quiet {
|
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();
|
term::blank();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: List matching working copy refs for all targets.
|
// 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 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 signer = term::signer(profile)?;
|
||||||
let patch = if draft {
|
let patch = if draft {
|
||||||
patches.draft(
|
patches.draft(
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,16 @@ blank is also okay.
|
||||||
|
|
||||||
fn select_patch(
|
fn select_patch(
|
||||||
patches: &patch::Patches,
|
patches: &patch::Patches,
|
||||||
workdir: &git::raw::Repository,
|
storage: &Repository,
|
||||||
head_branch: &git::raw::Branch,
|
head_branch: &git::raw::Branch,
|
||||||
target_oid: git::Oid,
|
target_oid: git::Oid,
|
||||||
whoami: &Did,
|
whoami: &Did,
|
||||||
) -> anyhow::Result<patch::PatchId> {
|
) -> anyhow::Result<patch::PatchId> {
|
||||||
let head_oid = branch_oid(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 mut result =
|
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 {
|
let Some((id, _, _)) = result.pop() else {
|
||||||
anyhow::bail!("No patches found to update, please specify a patch id");
|
anyhow::bail!("No patches found to update, please specify a patch id");
|
||||||
|
|
@ -40,7 +40,7 @@ fn select_patch(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_update_commit_info(
|
fn show_update_commit_info(
|
||||||
workdir: &git::raw::Repository,
|
storage: &Repository,
|
||||||
current_revision: &patch::Revision,
|
current_revision: &patch::Revision,
|
||||||
head_branch: &git::raw::Branch,
|
head_branch: &git::raw::Branch,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
|
@ -54,7 +54,7 @@ fn show_update_commit_info(
|
||||||
|
|
||||||
// Difference between the two revisions.
|
// Difference between the two revisions.
|
||||||
let head_oid = branch_oid(head_branch)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +79,7 @@ pub fn run(
|
||||||
|
|
||||||
let patch_id = match patch_id {
|
let patch_id = match patch_id {
|
||||||
Some(patch_id) => 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 {
|
let Ok(mut patch) = patches.get_mut(&patch_id) else {
|
||||||
anyhow::bail!("Patch `{patch_id}` not found");
|
anyhow::bail!("Patch `{patch_id}` not found");
|
||||||
|
|
@ -95,11 +95,11 @@ pub fn run(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !quiet {
|
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 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.get(REVISION_MSG)?;
|
||||||
let message = message.replace(REVISION_MSG.trim(), "");
|
let message = message.replace(REVISION_MSG.trim(), "");
|
||||||
let message = message.trim();
|
let message = message.trim();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue