55 lines
1.6 KiB
Rust
55 lines
1.6 KiB
Rust
use radicle::cob::patch;
|
|
use radicle::git;
|
|
use radicle::git::Oid;
|
|
use radicle::prelude::*;
|
|
use radicle::storage::git::Repository;
|
|
|
|
use crate::terminal as term;
|
|
use crate::terminal::patch::*;
|
|
|
|
/// Run patch update.
|
|
pub fn run(
|
|
patch_id: patch::PatchId,
|
|
base_id: Option<Oid>,
|
|
message: term::patch::Message,
|
|
profile: &Profile,
|
|
repository: &Repository,
|
|
workdir: &git::raw::Repository,
|
|
) -> anyhow::Result<()> {
|
|
// `HEAD`; This is what we are proposing as a patch.
|
|
let head_branch = try_branch(workdir.head()?)?;
|
|
|
|
let (_, target_oid) = get_merge_target(repository, &head_branch)?;
|
|
let mut patches = term::cob::patches_mut(profile, repository)?;
|
|
let Ok(mut patch) = patches.get_mut(&patch_id) else {
|
|
anyhow::bail!("Patch `{patch_id}` not found");
|
|
};
|
|
|
|
let head_oid = branch_oid(&head_branch)?;
|
|
let base_oid = match base_id {
|
|
Some(oid) => oid,
|
|
None => repository
|
|
.backend
|
|
.merge_base(target_oid.into(), head_oid.into())?
|
|
.into(),
|
|
};
|
|
|
|
// N.b. we don't update if both the head and base are the same as
|
|
// any previous revision
|
|
if patch
|
|
.revisions()
|
|
.any(|(_, revision)| revision.head() == head_oid && *revision.base() == base_oid)
|
|
{
|
|
return Ok(());
|
|
}
|
|
|
|
let (_, revision) = patch.latest();
|
|
let message = term::patch::get_update_message(message, workdir, revision, &head_oid.into())?;
|
|
let signer = term::signer(profile)?;
|
|
let revision = patch.update(message, base_oid, head_oid, &signer)?;
|
|
|
|
term::print(revision);
|
|
|
|
Ok(())
|
|
}
|