+ } 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")
+ }
+ }