use crate::repository::Repository;
use libanu::pristine::{Base32, MutTxnT, TxnT};
use libanu::MutTxnTExt;
use std::path::PathBuf;
#[derive(Clap, Debug)]
pub struct Unrecord {
#[clap(long = "repository")]
repo_path: Option<PathBuf>,
#[clap(long = "channel")]
channel: Option<String>,
#[clap(
about = "identifier of the change (unambiguous prefixes are accepted)",
multiple = true
)]
change_id: Vec<String>,
}
impl Unrecord {
pub fn run(self) -> Result<(), anyhow::Error> {
let repo = Repository::find_root(self.repo_path)?;
debug!("{:?}", repo.config);
let channel_name = repo.config.get_current_channel(self.channel.as_ref());
let mut txn = repo.pristine.mut_txn_begin();
for c in self.change_id.iter() {
let (hash, change_id) = txn.hash_from_prefix(c)?;
if let Some(mut channel) = txn.load_channel(channel_name) {
let mut can_unrecord = true;
let channel_ = channel.borrow();
for (p, d) in txn.iter_revdep(change_id) {
if p < change_id {
continue;
} else if p > change_id {
break;
}
if txn.get_changeset(&channel_.changes, d, None).is_some() {
if can_unrecord {
eprintln!("Cannot unrecord change {}, because the following changes depend on it:", c)
}
can_unrecord = false;
eprintln!(" {}", txn.get_external(d).unwrap().to_base32())
}
}
std::mem::drop(channel_);
if can_unrecord {
txn.unrecord(&repo.changes, &mut channel, &hash)?;
}
}
}
txn.commit()?;
Ok(())
}
}