} else if let Some(cap) = TAG.captures(&buf) {
if let Some(state) = Merkle::from_base32(cap[1].as_bytes()) {
let channel = load_channel(&*txn.read(), &cap[2])?;
let m = libpijul::pristine::current_state(&*txn.read(), &*channel.read())?;
if m == state {
let last_t = if let Some(n) =
txn.read().reverse_log(&*channel.read(), None)?.next()
{
n?.0.into()
} else {
bail!("Channel {} is empty", &cap[2]);
};
if txn.read().is_tagged(&channel.read().tags, last_t)? {
bail!("Current state is already tagged")
}
let mut tag_path = repo.changes_dir.clone();
std::fs::create_dir_all(&tag_path)?;
let mut temp_path = tag_path.clone();
temp_path.push("tmp");
let mut w = std::fs::File::create(&temp_path)?;
let size: usize = cap[3].parse().unwrap();
let mut buf = vec![0; size];
s.read_exact(&mut buf)?;
let header = bincode::deserialize(&buf)?;
libpijul::tag::from_channel(&*txn.read(), &cap[2], &header, &mut w)?;
libpijul::changestore::filesystem::push_tag_filename(&mut tag_path, &m);
std::fs::create_dir_all(tag_path.parent().unwrap())?;
std::fs::rename(&temp_path, &tag_path)?;
txn.write().put_tags(&mut *channel.write(), last_t.into())?;
} else {
bail!("Wrong state, cannot tag")
}
}