ZDK3GNDBWXJ2OXFDYB72ZCEBGLBF4MKE5K3PVHDZATHJ7HJIDPRQC
IVFOZZFZQLXBRXPKKR4YHCNZGNVIPG67NJICAGISDU6CMOHTQHBAC
H6JR7IAF5LHUDBRAQWAQLLNZR2ONBIXS5FJATAYCMJS7SYADCQLAC
27RZYCM3XP72CW7FYGE373YAFD6EEZOZ4YAHEKV6JE5L6Z5N3JNAC
SDCIBGQ5OJGCA24ZSZFTXIPGNNUAQPLYBEM56OKKIMPZ45U6CYFQC
S2B5MEWPPG4P6SL5NWTVAHPRJ6YPKX3VTRONYS267ZTTTPA6L3GAC
6UDRUL233PPKVB5ADZF6F2JM3BSW2GFNBKAGQFPTKPXIGOGJ4VLAC
HBUMCAFVS4W5FHWNZR7ITJFEEUCVZ4Q2U4KGWYN7XZGDZ75JMFTQC
43SISRQ4CLKXN5YVFAGWUU3OJBT2TX6QXWWER33ONLEITSCFCUBAC
GA3P7FOMATKDOGCZDYWLZJHAUNOWMRIP3BXTYFEH7PNWTTYYVLIAC
BC3QS46ORO56YB2LO3PRU74ITVOYFFKL3GGIBPV4M2DPH6NYJMEAC
CCLLB7OIFNFYJZTG3UCI7536TOCWSCSXR67VELSB466R24WLJSDAC
SXEYMYF7P4RZMZ46WPL4IZUTSQ2ATBWYZX7QNVMS3SGOYXYOHAGQC
YN63NUZO4LVJ7XPMURDULTXBVJKW5MVCTZ24R7Z52QMHO3HPDUVQC
GHO6DWPILBBTL6CVZKERJBTFL3EY6ZT4YM4E5R4S6YPGVFKFHCVAC
I52XSRUH5RVHQBFWVMAQPTUSPAJ4KNVID2RMI3UGCVKFLYUO6WZAC
A3RM526Y7LUXNYW4TL56YKQ5GVOK2R5D7JJVTSQ6TT5MEXIR6YAAC
76PCXGML77EZWTRI5E6KHLVRAFTJ2AB5YRN5EKOYNAPKTWY2KCGAC
UDHP4ZVBQZT2VBURB2MDCU2IZDNMCAFSIUKWRBDQ5BWMFKSN2LYQC
QZ77NIXCOQDZJTTVQNN22CAZSMRPGVOZAW4X6RKIZ534UG4XCWEQC
2D7P2VKJASU7QDQZHGCLBIT6G2V5WUFYLWTCEVVEI2EZHGM6XYRAC
WKX5S4Z4DOB5S6A6X5V6ECZFCHQUMWRGX5XT4FBOG57P6HPWK7CAC
C5XGFNKIX3RM6KOKRYTECBDDRDAE33JWIVJAJJTEFKFXQNXHEKHQC
ISCWVXO6UN37V2QMR75ZWS7H5E7WYZCGR6TX3EDFOFRVCAPMIVUAC
QL6K2ZM35B3NIXEMMCJWUSFXOBQHAGXRDMO7ID5DCKTJH4QJVY7QC
AAXP2534BWX2ZUDZZHUMLYDBMGFGUH32CNRA3KOLER3JKOIJUZLAC
6F6AAHK4M2IVS23TVISR5OJSTZXUSEKLOP5BMM7SUHYG2FQNTSGQC
A3DMBJJAPLS6ASSZ7JVVVULRQNZCF2WKYTRUD7EY7PKVYABSATFAC
LOJL4HMYG7EOVZ5MSMCORDLDSRHWO2JPHMOTLMLQA7GPJNSVDXOQC
PIQCNEEBNHZDYOU2O7667XBB6D3V2MUALRRVJX6VO5BGYR7LTYRQC
FXEDPLRI7PXLDXV634ZA6D5Q3ZWG3ESTKJTMRPJ4MAHI7PKU3M6AC
ZHABNS3S6FSINO74FOI5KHYXYDTBPO4FQTTYTUS7NNKEVVNLYC4AC
VO5OQW4W2656DIYYRNZ3PO7TQ4JOKQ3GVWE5ALUTYVMX3WMXJOYQC
HSEYMLO2DJCDGBO4F7T6NFMFSZ4TMSOBH5XGIU5NYOEFKUSV5UKAC
2RXOCWUWOGHEKHT5W73LAHJSOZVRTOGS7BWLSIGEEEBJGMCZBXQAC
I24UEJQLCH2SOXA4UHIYWTRDCHSOPU7AFTRUOTX7HZIAV4AZKYEQC
OJZWJUF2TCGZ7RFVY6FPKBS5P3C4BGHZDPVH775OHVNVFMJICKNQC
7UPL3Y2A5QOBU6VIUHNWEFGSGQ5CMWGDGOVLRZ53UARXG3TDGLMAC
P6WE7YKL6ILKLYKMJUJLGINN7L4U7X4KUIE5ELTK2LEENX3DUBCQC
6YMDOZIB5LVYLFIDGN2WNT5JTHEAMS4TFPVDEZ3OWXWOKJOC5QDAC
X7OHUPL5VYT6ECER2KNGRNFLRX7SBZOM5QWSQ4PBO2UPIE7XM6MAC
5FI6SBEZ6RERERUAIWQJVAY66BEZ7YQOYOUNK2DPOLRGS2X326RAC
LERRJNFC6324RC6ADDTEPCNR3MYH6GKIQUDD433ZAIEECFF5CADAC
AJEH3FSPKLBYSRQQQ4UL4QA3SPT4MHIC4VEM3XDVATMFFU3R7JKAC
RMDMAYRXYBU5OQXV5HSF6LFD4NBMKRNH5EPIVW3K5HAV6D56IG6QC
O4DNWMPDUWI6SKYOZTQKCSX6MSR73CTGCUSM65TSQYVOUSAAS6KAC
7KNPYIDUXCBZ65NA74NL2DIFS6STJWN4XXHXLTIV5QXZSVLARJMAC
TVVW53HZGYPODAXEQ4BFZNSPBOFG6JEDVOKIYIDZMWFAMOBKOR2QC
ZSF3YFZTDOXMCOC3HOT5C6MQLYLWOR7QJAOUDS2M2Z4SC2YW3GRAC
3S6LU2U5TIU43WRE5RQS3IOLVJLVNCDL4W44FVK2HR3NAXZ7IDUAC
SBSM3VZVFD2A5MD5P3XEUH4LFONYABZCKRNAGIHGTSZOG2QS5SYAC
5BRU2RRWOQBMS2V3RQM7PRFR5UILYZ73GISHAKJA6KIZGC5M2MFAC
IIV3EL2XYI2X7HZWKXEXQFAE3R3KC2Q7SGOT3Q332HSENMYVF32QC
3AMEP2Y5J6GA4AWQONF4JVA3XSR3ASLHHKMYG44R72SOUY3UQCDAC
XA23FMQM2AI7RMR36AYN7UNP2D5JWVJMJPHURWZO7URM7H46PU6AC
GBX4AFASHNICJ25B6PAGXP3C3NJ5PPXZ76STLDVPBUVEGDJP5ZAAC
YCEZL7VFBZNOZTSSI24D36ACJVZKXCCEOIFWIHQWK22QPB4PDTRAC
VNBLGT6GAN2AHKRFKTKED7WNDDRGNULY5H343ZYV3ETSDZZKGBTAC
LPM4PBYJFIFZXN3JNEZOKEQ74UXUMURIFY5U4R2CFC6N4XINHL4AC
EAAJNZ3J57QH5P5UWJD5CRN62HZKCRW5BKLUCIHSFFKXLUVEFH2AC
GJZWSXHQ6SYUDTVDOUBTJYU3SG567M2AXWURWKRNVP2MISZ444DQC
I3OVP3NHSMB2YLU4EPU5BFH7KB54PMQ4WDATGINIJKRIHMSVFUSQC
YGPEHOTED5UG3IUK263PIX566VEHM3KYHPYIXZHPJ4ICHXWZEUJAC
RRCSHAYZ6RLWVPNYHF2F5FSRL2KKJNPQUQRIJYLJGB23BZQQ7JLQC
MDADYULS5AWVMTJDGYCGNQTN6T7XJDRUBDTFILDY5MLF6I2PE5NAC
LCERQSWMA2YKOPAPNZUSOQ7FLBGDHBZR33OHLYX7T4KTKULRMJDQC
CXM5CBS27BL35Z6TRCI7OS4AHWVJ4VFND7HECGAUC74ZQ5KFZXLAC
7ZFRYVVQQGJYG3POPWJWL3CDW37YDXZYZQC3OSWFHWEUSEMYQ4EQC
XR7MNOMU5PMOOEY2EPPUABZ7NOP432RDCWUET23ONPXTT3JQIFIAC
2VXTRPO4OML5A2RPI7SAEV5SJNOFIVS4TMYYG6TUUS5EXFMAPRJAC
5SLOJYHGPMZVCOE3IS7ICNMJJYX3RBT6CDG5MAV6T4CJIOW7YZ6QC
HMMMKONLCRAXVT7SO2ITTFDOJIQKKVSRIZPXYVPDC34RCBHWMHVAC
U2CGP7OPHQZNAAPWCRSFVZQWXFRVCB2NC3APRA7ACQJZBIVBE6IQC
IXC43DSHDSXCE2X6H6N47GGVKTYM2D2BUUWF34CFWMFT6Z45NOOAC
6XDVUSBMBXM4LKKKR7YPJ5PF4ISOZNT465GSOFR2GF7NTL5SNLZAC
QJXNUQFJOAPQT3GUXRDTVKMJZCKFONSXUZMAZB7VC7OHDCGAVCOQC
XF3FRWJ6MFZAMR2NFEBICRCG42QEPSKSWJSBOJYLA3LX2UYJ5FMQC
VKBJ6XB64MVCKJ4TWX2T4XUBEOKD55WW6CUF47DINVZQGSCVAXJAC
fn #name_get<'txn>(&'txn self, db: &Self::#name_capital, key: &#key, value: Option<&#value>) -> Result<Option<&'txn #value>, TxnErr<Self::#error>> {
fn #name_get<'txn>(&'txn self, db: &Self::#name_capital, key: &#key, value: Option<&#value>) -> Result<Option<&'txn #value>, #txnerr<Self::#error>> {
fn #name_get<'txn>(&'txn self, db: &Self::#name_capital, key: &#key, value: Option<&#value>) -> Result<Option<&'txn #value>, TxnErr<Self::#error>>;
fn #name_get<'txn>(&'txn self, db: &Self::#name_capital, key: &#key, value: Option<&#value>) -> Result<Option<&'txn #value>, #txnerr<Self::#error>>;
) -> Result<bool, TxnErr<Self::#error>> {
Ok(::sanakirja::btree::put(&mut self.txn, &mut self.#name, k, v).map_err(TxnErr)?)
) -> Result<bool, #txnerr<Self::#error>> {
Ok(::sanakirja::btree::put(&mut self.txn, &mut self.#name, k, v).map_err(#txnerr)?)
) -> Result<bool, TxnErr<Self::#error>> {
Ok(::sanakirja::btree::del(&mut self.txn, &mut self.#name, k, v).map_err(TxnErr)?)
) -> Result<bool, #txnerr<Self::#error>> {
Ok(::sanakirja::btree::del(&mut self.txn, &mut self.#name, k, v).map_err(#txnerr)?)
},
/// Restore a tag into a new channel.
#[clap(name = "reset")]
Reset {
/// Set the repository where this command should run. Defaults to
/// the first ancestor of the current directory that contains a
/// `.pijul` directory.
#[clap(long = "repository")]
repo_path: Option<PathBuf>,
tag: String,
}
Some(SubCommand::Reset { repo_path, tag }) => {
let repo = Repository::find_root(repo_path)?;
let mut tag_path = repo.path.join(libpijul::DOT_DIR);
tag_path.push("tags");
let h = if let Some(h) = libpijul::Hash::from_base32(tag.as_bytes()) {
libpijul::changestore::filesystem::push_filename(&mut tag_path, &h);
h
} else {
super::find_hash(&mut tag_path, &tag)?
};
let tag = libpijul::tag::txn::TagTxn::new(&tag_path).unwrap();
let txn = libpijul::tag::txn::WithTag {
tag,
txn: repo.pristine.mut_txn_begin()?,
};
let channel = txn.channel();
let txn = ArcTxn::new(txn);
libpijul::output::output_repository_no_pending_(
&repo.working_copy,
&repo.changes,
&txn,
&channel,
"",
true,
None,
num_cpus::get(),
0,
)?;
if let Ok(txn) = std::sync::Arc::try_unwrap(txn.0) {
txn.into_inner().txn.commit()?
}
writeln!(stdout, "Reset to tag {}", h.to_base32())?;
#[derive(Debug, Error)]
pub enum Error<C: std::error::Error + 'static, T: std::error::Error + 'static> {
impl<T: GraphTxnT + TreeTxnT> std::fmt::Debug for AddError<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
AddError::Ignore(e) => std::fmt::Debug::fmt(e, fmt),
AddError::Io(e) => std::fmt::Debug::fmt(e, fmt),
AddError::Fs(e) => std::fmt::Debug::fmt(e, fmt),
}
}
}
#[derive(Error)]
pub enum Error<C: std::error::Error + 'static, T: GraphTxnT + TreeTxnT> {
Txn(#[from] T),
Txn(#[from] TxnErr<T::GraphError>),
#[error(transparent)]
Tree(#[from] TreeErr<T::TreeError>),
}
impl<C: std::error::Error + 'static, T: GraphTxnT + TreeTxnT> std::fmt::Debug for Error<C, T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Error::Add(e) => std::fmt::Debug::fmt(e, fmt),
Error::Record(e) => std::fmt::Debug::fmt(e, fmt),
Error::Txn(e) => std::fmt::Debug::fmt(e, fmt),
Error::Tree(e) => std::fmt::Debug::fmt(e, fmt),
}
}
pub fn undo_file_deletion<
T: ChannelTxnT + TreeMutTxnT + TreeTxnT<TreeError = <T as GraphTxnT>::GraphError>,
P: ChangeStore,
>(
pub fn undo_file_deletion<T: ChannelTxnT + TreeMutTxnT + TreeTxnT, P: ChangeStore>(
fn restore_inode<
T: TreeMutTxnT + GraphTxnT + TreeTxnT<TreeError = <T as GraphTxnT>::GraphError>,
P: ChangeStore,
>(
fn restore_inode<T: TreeMutTxnT + GraphTxnT + TreeTxnT, P: ChangeStore>(
#[derive(Debug, Error)]
pub enum UnrecordError<
ChangestoreError: std::error::Error + 'static,
TxnError: std::error::Error + 'static,
> {
#[derive(Error)]
pub enum UnrecordError<ChangestoreError: std::error::Error + 'static, T: GraphTxnT + TreeTxnT> {
impl<T: std::error::Error + 'static, C: std::error::Error + 'static> std::convert::From<TxnErr<T>>
for UnrecordError<C, T>
{
fn from(t: TxnErr<T>) -> Self {
UnrecordError::Txn(t.0)
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT> std::fmt::Debug for UnrecordError<C, T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
UnrecordError::Changestore(e) => std::fmt::Debug::fmt(e, fmt),
UnrecordError::Txn(e) => std::fmt::Debug::fmt(e, fmt),
UnrecordError::Tree(e) => std::fmt::Debug::fmt(e, fmt),
UnrecordError::Block(e) => std::fmt::Debug::fmt(e, fmt),
UnrecordError::InconsistentChange(e) => std::fmt::Debug::fmt(e, fmt),
UnrecordError::ChangeNotInChannel { hash } => {
write!(fmt, "Change not in channel: {}", hash.to_base32())
}
UnrecordError::ChangeIsDependedUpon {
change_id,
dependent,
} => write!(
fmt,
"Change {} is depended upon: {}",
change_id.to_base32(),
dependent.to_base32()
),
UnrecordError::Missing(e) => std::fmt::Debug::fmt(e, fmt),
UnrecordError::LocalApply(e) => std::fmt::Debug::fmt(e, fmt),
UnrecordError::Apply(e) => std::fmt::Debug::fmt(e, fmt),
}
fn go(hunk: PrintableHunk) {
fn go(mut hunk: PrintableHunk) {
match hunk {
PrintableHunk::FileAddition {
ref perms,
ref mut contents,
..
} => {
if let PrintablePerms::IsDir = perms {
contents.clear()
}
}
PrintableHunk::FileDel {
ref mut del_edges, ..
} => {
if del_edges.is_empty() {
del_edges.push(PrintableEdge::arbitrary(&mut Gen::new(3)))
}
}
PrintableHunk::FileUndel {
ref mut undel_edges,
..
} => {
if undel_edges.is_empty() {
undel_edges.push(PrintableEdge::arbitrary(&mut Gen::new(3)))
}
}
PrintableHunk::Replace {
ref mut change_contents,
ref mut replacement_contents,
..
} => {
if change_contents.is_empty() {
change_contents.push(b'a')
}
if replacement_contents.is_empty() {
replacement_contents.push(b'b')
}
}
PrintableHunk::Edit {
ref mut change,
ref mut contents,
..
} => {
if let PrintableAtom::Edges(ref mut change) = change {
if change.is_empty() {
change.push(PrintableEdge::arbitrary(&mut Gen::new(3)))
}
}
if std::str::from_utf8(contents).is_err() {
contents.clear();
contents.extend(b"bla\n".iter().cloned())
}
}
_ => {}
}
#[derive(Debug, Error)]
pub enum RecordError<
C: std::error::Error + 'static,
W: std::error::Error,
T: std::error::Error + 'static,
> {
#[derive(Error)]
pub enum RecordError<C: std::error::Error + 'static, W: std::error::Error, T: GraphTxnT + TreeTxnT>
{
impl<
C: std::error::Error + 'static,
W: std::error::Error + 'static,
T: std::error::Error + 'static,
> std::convert::From<TxnErr<T>> for RecordError<C, W, T>
impl<C: std::error::Error, W: std::error::Error, T: GraphTxnT + TreeTxnT> std::fmt::Debug
for RecordError<C, W, T>
fn from(e: TxnErr<T>) -> Self {
RecordError::Txn(e.0)
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
RecordError::Changestore(e) => std::fmt::Debug::fmt(e, fmt),
RecordError::WorkingCopy(e) => std::fmt::Debug::fmt(e, fmt),
RecordError::SystemTimeError(e) => std::fmt::Debug::fmt(e, fmt),
RecordError::Txn(e) => std::fmt::Debug::fmt(e, fmt),
RecordError::Tree(e) => std::fmt::Debug::fmt(e, fmt),
RecordError::Diff(e) => std::fmt::Debug::fmt(e, fmt),
RecordError::PathNotInRepo(p) => write!(fmt, "Path not in repository: {}", p),
RecordError::Io(e) => std::fmt::Debug::fmt(e, fmt),
}
impl<
C: std::error::Error + 'static,
W: std::error::Error + 'static,
T: std::error::Error + 'static,
> std::convert::From<crate::output::FileError<C, T>> for RecordError<C, W, T>
impl<C: std::error::Error + 'static, W: std::error::Error + 'static, T: GraphTxnT + TreeTxnT>
std::convert::From<crate::output::FileError<C, T>> for RecordError<C, W, T>
fn delete_obsolete_children<
T: GraphTxnT + TreeTxnT<TreeError = <T as GraphTxnT>::GraphError>,
W: WorkingCopyRead,
C: ChangeStore,
>(
fn delete_obsolete_children<T: GraphTxnT + TreeTxnT, W: WorkingCopyRead, C: ChangeStore>(
fn push_children<
'a,
T: ChannelTxnT + TreeTxnT<TreeError = <T as GraphTxnT>::GraphError>,
W: WorkingCopyRead,
C: ChangeStore,
>(
fn push_children<'a, T: ChannelTxnT + TreeTxnT, W: WorkingCopyRead, C: ChangeStore>(
fn record_existing_file<
T: ChannelTxnT + TreeTxnT<TreeError = <T as GraphTxnT>::GraphError>,
W: WorkingCopyRead + Clone,
C: ChangeStore,
>(
fn record_existing_file<T: ChannelTxnT + TreeTxnT, W: WorkingCopyRead + Clone, C: ChangeStore>(
fn record_nondeleted<
T: ChannelTxnT + TreeTxnT<TreeError = <T as GraphTxnT>::GraphError>,
W: WorkingCopyRead + Clone,
C: ChangeStore,
>(
fn record_nondeleted<T: ChannelTxnT + TreeTxnT, W: WorkingCopyRead + Clone, C: ChangeStore>(
fn record_deleted_file<
T: GraphTxnT + TreeTxnT<TreeError = <T as GraphTxnT>::GraphError>,
W: WorkingCopyRead,
C: ChangeStore,
>(
fn record_deleted_file<T: GraphTxnT + TreeTxnT, W: WorkingCopyRead, C: ChangeStore>(
find_block_end(&self.txn, &graph.graph, p)
Ok(find_block_end(&self.txn, &graph.graph, p)?)
}
}
impl std::convert::From<BlockError<::sanakirja::Error>> for BlockError<SanakirjaError> {
fn from(e: BlockError<::sanakirja::Error>) -> Self {
match e {
BlockError::Txn(t) => BlockError::Txn(t.into()),
BlockError::Block { block } => BlockError::Block { block },
}
sanakirja_table_get!(inodes, Inode, Position<ChangeId>, TreeError);
sanakirja_table_get!(revinodes, Position<ChangeId>, Inode, TreeError);
sanakirja_cursor!(inodes, Inode, Position<ChangeId>);
sanakirja_table_get!(inodes, Inode, Position<ChangeId>, TreeError, TreeErr);
sanakirja_table_get!(revinodes, Position<ChangeId>, Inode, TreeError, TreeErr);
sanakirja_cursor!(inodes, Inode, Position<ChangeId>, TreeErr);
sanakirja_put_del!(inodes, Inode, Position<ChangeId>, TreeError);
sanakirja_put_del!(revinodes, Position<ChangeId>, Inode, TreeError);
sanakirja_put_del!(inodes, Inode, Position<ChangeId>, TreeError, TreeErr);
sanakirja_put_del!(revinodes, Position<ChangeId>, Inode, TreeError, TreeErr);
Ok(btree::del(
&mut self.txn,
&mut self.partials,
&k,
e.as_ref(),
)?)
btree::del(&mut self.txn, &mut self.partials, &k, e.as_ref()).map_err(|e| TreeErr(e.into()))
table_get!(inodes, Inode, Position<ChangeId>, TreeError);
table_get!(revinodes, Position<ChangeId>, Inode, TreeError);
table_get!(inodes, Inode, Position<ChangeId>, TreeError, TreeErr);
table_get!(revinodes, Position<ChangeId>, Inode, TreeError, TreeErr);
cursor!(partials, SmallStr, Position<ChangeId>, TreeError);
cursor!(inodes, Inode, Position<ChangeId>, TreeError);
cursor!(partials, SmallStr, Position<ChangeId>, TreeError, TreeErr);
cursor!(inodes, Inode, Position<ChangeId>, TreeError, TreeErr);
initialized_cursor!(tree, PathId, Inode, TreeTxnT, TreeError);
initialized_cursor!(revtree, Inode, PathId, TreeTxnT, TreeError);
initialized_cursor!(tree, PathId, Inode, TreeTxnT, TreeError, TreeErr);
initialized_cursor!(revtree, Inode, PathId, TreeTxnT, TreeError, TreeErr);
initialized_cursor!(inodes, Inode, Position<ChangeId>, TreeTxnT, TreeError);
initialized_cursor!(revinodes, Position<ChangeId>, Inode, TreeTxnT, TreeError);
initialized_cursor!(
inodes,
Inode,
Position<ChangeId>,
TreeTxnT,
TreeError,
TreeErr
);
initialized_cursor!(
revinodes,
Position<ChangeId>,
Inode,
TreeTxnT,
TreeError,
TreeErr
);
put_del!(inodes, Inode, Position<ChangeId>, TreeError);
put_del!(revinodes, Position<ChangeId>, Inode, TreeError);
put_del!(tree, PathId, Inode, TreeError);
put_del!(revtree, Inode, PathId, TreeError);
put_del!(inodes, Inode, Position<ChangeId>, TreeError, TreeErr);
put_del!(revinodes, Position<ChangeId>, Inode, TreeError, TreeErr);
put_del!(tree, PathId, Inode, TreeError, TreeErr);
put_del!(revtree, Inode, PathId, TreeError, TreeErr);
T: MutTxnT + Send + Sync + 'static,
T: ChannelMutTxnT + TreeMutTxnT<TreeError = T::GraphError> + Send + Sync + 'static,
R: WorkingCopy + Send + Clone + Sync + 'static,
P: ChangeStore + Send + Clone + 'static,
>(
repo: &R,
changes: &P,
txn: &ArcTxn<T>,
channel: &ChannelRef<T>,
prefix: &str,
output_name_conflicts: bool,
if_modified_since: Option<std::time::SystemTime>,
n_workers: usize,
salt: u64,
) -> Result<BTreeSet<Conflict>, OutputError<P::Error, T, R::Error>>
where
T::Channel: Send + Sync + 'static,
{
debug!("output_repository_no_pending: {:?}", prefix);
let (c, f) = output_repository(
repo,
changes,
txn.clone(),
channel.clone(),
ChangeId::ROOT,
&mut crate::path::components(prefix),
output_name_conflicts,
if_modified_since,
n_workers,
salt,
)?;
del_redundant(txn.clone(), channel.clone(), &f)?;
Ok(c)
}
/// Output updates the working copy after applying changes, including
/// the graph-file correspondence.
///
/// **WARNING:** This overwrites the working copy, cancelling any
/// unrecorded change.
pub fn output_repository_no_pending_<
T: ChannelTxnT + TreeMutTxnT + Send + Sync + 'static,
) -> Result<(), OutputError<P::Error, T::GraphError, W::Error>> {
let mut forward = Vec::new();
{
let txn = txn.read();
let channel = channel.read();
let mut l = retrieve(&*txn, txn.graph(&*channel), output_item.pos)?;
let w = repo
.write_file(&path, inode)
.map_err(OutputError::WorkingCopy)?;
let mut f = vertex_buffer::ConflictsWriter::new(w, &path, conflicts);
alive::output_graph(changes, &*txn, &*channel, &mut f, &mut l, &mut forward)
.map_err(PristineOutputError::from)?;
use std::io::Write;
f.w.flush().unwrap_or(())
}
forward: &mut Vec<Redundant>,
) -> Result<(), OutputError<P::Error, T, W::Error>> {
let txn = txn.read();
let channel = channel.read();
let mut l = retrieve(&*txn, txn.graph(&*channel), output_item.pos)?;
let w = repo
.write_file(&path, inode)
.map_err(OutputError::WorkingCopy)?;
let mut f = vertex_buffer::ConflictsWriter::new(w, &path, conflicts);
alive::output_graph(changes, &*txn, &*channel, &mut f, &mut l, forward)
.map_err(PristineOutputError::from)?;
use std::io::Write;
f.w.flush().unwrap_or(());
Ok(())
}
fn del_redundant<T: ChannelMutTxnT + GraphMutTxnT>(
txn: ArcTxn<T>,
channel: ChannelRef<T>,
forward: &[Redundant],
) -> Result<(), TxnErr<T::GraphError>> {
let dest = *txn.find_block(txn.graph(&*channel), edge.dest()).unwrap();
debug!("deleting forward edge {:?} {:?} {:?}", vertex, dest, edge);
let dest = *txn.find_block(txn.graph(&*channel), ve.e.dest()).unwrap();
debug!("deleting forward edge {:?} {:?} {:?}", ve.v, dest, ve.e);
#[derive(Debug, Error)]
pub enum PristineOutputError<ChangestoreError: std::error::Error, Txn: std::error::Error + 'static>
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT, W: std::error::Error + Send> std::fmt::Debug
for OutputError<C, T, W>
#[error(transparent)]
Txn(Txn),
#[error("Changestore error: {0}")]
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
OutputError::WorkingCopy(e) => std::fmt::Debug::fmt(e, fmt),
OutputError::Pristine(e) => std::fmt::Debug::fmt(e, fmt),
}
}
}
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT, W: std::error::Error + Send> std::fmt::Display
for OutputError<C, T, W>
{
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
OutputError::WorkingCopy(e) => std::fmt::Display::fmt(e, fmt),
OutputError::Pristine(e) => std::fmt::Display::fmt(e, fmt),
}
}
}
#[derive(Error)]
pub enum PristineOutputError<ChangestoreError: std::error::Error, T: GraphTxnT + TreeTxnT> {
Channel(#[from] TxnErr<T::GraphError>),
Tree(#[from] TreeErr<T::TreeError>),
impl<C: std::error::Error, T: std::error::Error + 'static> From<TxnErr<T>>
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT> std::fmt::Debug for PristineOutputError<C, T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
PristineOutputError::Channel(e) => std::fmt::Debug::fmt(e, fmt),
PristineOutputError::Tree(e) => std::fmt::Debug::fmt(e, fmt),
PristineOutputError::Changestore(e) => std::fmt::Debug::fmt(e, fmt),
PristineOutputError::Io(e) => std::fmt::Debug::fmt(e, fmt),
PristineOutputError::Fs(e) => std::fmt::Debug::fmt(e, fmt),
}
}
}
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT> std::fmt::Display
fn from(e: TxnErr<T>) -> Self {
PristineOutputError::Txn(e.0)
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
PristineOutputError::Channel(e) => std::fmt::Display::fmt(e, fmt),
PristineOutputError::Tree(e) => std::fmt::Display::fmt(e, fmt),
PristineOutputError::Changestore(e) => std::fmt::Display::fmt(e, fmt),
PristineOutputError::Io(e) => std::fmt::Display::fmt(e, fmt),
PristineOutputError::Fs(e) => std::fmt::Display::fmt(e, fmt),
}
impl<C: std::error::Error, T: std::error::Error + 'static, W: std::error::Error + Send>
From<TxnErr<T>> for OutputError<C, T, W>
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT, W: std::error::Error + Send>
From<TxnErr<T::GraphError>> for OutputError<C, T, W>
#[derive(Debug, Error)]
pub enum FileError<ChangestoreError: std::error::Error + 'static, T: std::error::Error + 'static> {
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT, W: std::error::Error + Send>
From<TreeErr<T::TreeError>> for OutputError<C, T, W>
{
fn from(e: TreeErr<T::TreeError>) -> Self {
OutputError::Pristine(e.into())
}
}
#[derive(Error)]
pub enum FileError<ChangestoreError: std::error::Error + std::fmt::Debug + 'static, T: GraphTxnT> {
impl<C: std::error::Error, T: std::error::Error + 'static> From<FileError<C, T>>
// Why can't I just derive Debug for `FileError`? The following is
// what I expect the derived impl would be.
impl<ChangestoreError: std::error::Error + std::fmt::Debug + 'static, T: GraphTxnT> std::fmt::Debug
for FileError<ChangestoreError, T>
{
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
FileError::Changestore(ref c) => std::fmt::Debug::fmt(c, fmt),
FileError::Txn(ref c) => std::fmt::Debug::fmt(c, fmt),
FileError::Io(ref c) => std::fmt::Debug::fmt(c, fmt),
}
}
}
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT> From<FileError<C, T>>
impl<
P: std::error::Error + 'static,
T: std::error::Error + 'static,
A: std::error::Error + 'static,
> std::convert::From<TxnErr<T>> for ArchiveError<P, T, A>
impl<P: std::error::Error + 'static, T: GraphTxnT + TreeTxnT, A: std::error::Error + 'static>
std::fmt::Debug for ArchiveError<P, T, A>
fn from(e: TxnErr<T>) -> Self {
ArchiveError::Txn(e.0)
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ArchiveError::A(e) => std::fmt::Debug::fmt(e, fmt),
ArchiveError::P(e) => std::fmt::Debug::fmt(e, fmt),
ArchiveError::Txn(e) => std::fmt::Debug::fmt(e, fmt),
ArchiveError::Tree(e) => std::fmt::Debug::fmt(e, fmt),
ArchiveError::Unrecord(e) => std::fmt::Debug::fmt(e, fmt),
ArchiveError::Apply(e) => std::fmt::Debug::fmt(e, fmt),
ArchiveError::File(e) => std::fmt::Debug::fmt(e, fmt),
ArchiveError::Output(e) => std::fmt::Debug::fmt(e, fmt),
ArchiveError::StateNotFound { state } => write!(fmt, "State not found: {:?}", state),
}
) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, Self::GraphError, A::Error>>
{
) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, Self, A::Error>> {
) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, Self::GraphError, A::Error>>
{
) -> Result<Vec<output::Conflict>, output::ArchiveError<P::Error, Self, A::Error>> {
) -> Result<
(pristine::Position<pristine::ChangeId>, bool),
fs::FsErrorC<C::Error, Self::GraphError>,
> {
) -> Result<(pristine::Position<pristine::ChangeId>, bool), fs::FsErrorC<C::Error, Self>> {
#[derive(Debug, Error)]
pub enum FsErrorC<C: std::error::Error + 'static, T: std::error::Error + 'static> {
impl<T: TreeTxnT> std::fmt::Debug for FsError<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
FsError::NotFound(e) => std::fmt::Debug::fmt(e, fmt),
FsError::AlreadyInRepo(e) => write!(fmt, "File already in repository: {}", e),
FsError::Tree(e) => std::fmt::Debug::fmt(e, fmt),
FsError::InvalidPath(e) => write!(fmt, "Invalid path: {}", e),
}
}
}
#[derive(Error)]
pub enum FsErrorC<C: std::error::Error + 'static, T: GraphTxnT> {
impl<C: std::error::Error + 'static, T: GraphTxnT> std::fmt::Debug for FsErrorC<C, T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
FsErrorC::Txn(e) => std::fmt::Debug::fmt(e, fmt),
FsErrorC::Changestore(e) => std::fmt::Debug::fmt(e, fmt),
FsErrorC::NotFound(e) => std::fmt::Debug::fmt(e, fmt),
}
}
}
impl<T: std::error::Error + 'static> std::convert::From<TxnErr<T>> for FsError<T> {
fn from(e: TxnErr<T>) -> Self {
FsError::Txn(e.0)
}
}
impl<C: std::error::Error + 'static, T: std::error::Error + 'static> std::convert::From<TxnErr<T>>
for FsErrorC<C, T>
{
fn from(e: TxnErr<T>) -> Self {
FsErrorC::Txn(e.0)
}
}
impl<T: std::error::Error + 'static, C: std::error::Error + 'static> std::convert::From<TxnErr<T>>
for DiffError<C, T>
{
fn from(e: TxnErr<T>) -> Self {
DiffError::Txn(e.0)
impl<P: std::error::Error, T: GraphTxnT> std::fmt::Debug for DiffError<P, T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
DiffError::Output(e) => std::fmt::Debug::fmt(e, fmt),
DiffError::Txn(e) => std::fmt::Debug::fmt(e, fmt),
}
#[derive(Debug, Error)]
pub enum ApplyError<ChangestoreError: std::error::Error, TxnError: std::error::Error + 'static> {
#[error("Changestore error: {0}")]
pub enum ApplyError<ChangestoreError: std::error::Error, T: GraphTxnT + TreeTxnT> {
#[error("Local change error: {err}")]
LocalChange {
#[from]
err: LocalApplyError<TxnError>,
},
LocalChange(LocalApplyError<T>),
}
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT> std::fmt::Debug for ApplyError<C, T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ApplyError::Changestore(e) => std::fmt::Debug::fmt(e, fmt),
ApplyError::LocalChange(e) => std::fmt::Debug::fmt(e, fmt),
}
}
}
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT> std::fmt::Display for ApplyError<C, T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ApplyError::Changestore(e) => std::fmt::Display::fmt(e, fmt),
ApplyError::LocalChange(e) => std::fmt::Display::fmt(e, fmt),
}
}
#[derive(Debug, Error)]
pub enum LocalApplyError<TxnError: std::error::Error + 'static> {
#[error("Dependency missing: {:?}", hash)]
#[derive(Error)]
pub enum LocalApplyError<T: GraphTxnT + TreeTxnT> {
impl<TxnError: std::error::Error> LocalApplyError<TxnError> {
fn from_missing(err: MissingError<TxnError>) -> Self {
match err {
MissingError::Txn(e) => LocalApplyError::Txn(e),
MissingError::Block(e) => e.into(),
MissingError::Inconsistent(_) => LocalApplyError::InvalidChange,
impl<T: GraphTxnT + TreeTxnT> std::fmt::Debug for LocalApplyError<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
LocalApplyError::DependencyMissing { hash } => {
write!(fmt, "Dependency missing: {:?}", hash)
}
LocalApplyError::ChangeAlreadyOnChannel { hash } => {
write!(fmt, "Change already on channel: {:?}", hash)
}
LocalApplyError::Txn(e) => std::fmt::Debug::fmt(e, fmt),
LocalApplyError::Tree(e) => std::fmt::Debug::fmt(e, fmt),
LocalApplyError::Block { block } => write!(fmt, "Block error: {:?}", block),
LocalApplyError::InvalidChange => write!(fmt, "Invalid change"),
impl<T: std::error::Error> From<crate::pristine::InconsistentChange<T>> for LocalApplyError<T> {
fn from(err: crate::pristine::InconsistentChange<T>) -> Self {
match err {
InconsistentChange::Txn(e) => LocalApplyError::Txn(e),
_ => LocalApplyError::InvalidChange,
impl<T: GraphTxnT + TreeTxnT> std::fmt::Display for LocalApplyError<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
LocalApplyError::DependencyMissing { hash } => {
write!(fmt, "Dependency missing: {:?}", hash)
}
LocalApplyError::ChangeAlreadyOnChannel { hash } => {
write!(fmt, "Change already on channel: {:?}", hash)
}
LocalApplyError::Txn(e) => std::fmt::Display::fmt(e, fmt),
LocalApplyError::Tree(e) => std::fmt::Display::fmt(e, fmt),
LocalApplyError::Block { block } => write!(fmt, "Block error: {:?}", block),
LocalApplyError::InvalidChange => write!(fmt, "Invalid change"),
impl<T: std::error::Error> From<crate::pristine::TxnErr<T>> for LocalApplyError<T> {
fn from(err: crate::pristine::TxnErr<T>) -> Self {
LocalApplyError::Txn(err.0)
impl<C: std::error::Error, T: GraphTxnT + TreeTxnT> From<crate::pristine::TxnErr<T::GraphError>>
for ApplyError<C, T>
{
fn from(err: crate::pristine::TxnErr<T::GraphError>) -> Self {
ApplyError::LocalChange(LocalApplyError::Txn(err))
impl<T: std::error::Error> From<crate::pristine::BlockError<T>> for LocalApplyError<T> {
fn from(err: crate::pristine::BlockError<T>) -> Self {
impl<T: GraphTxnT + TreeTxnT> LocalApplyError<T> {
fn from_missing(err: MissingError<T::GraphError>) -> Self {
BlockError::Txn(e) => LocalApplyError::Txn(e),
MissingError::Txn(e) => LocalApplyError::Txn(TxnErr(e)),
MissingError::Block(e) => e.into(),
MissingError::Inconsistent(_) => LocalApplyError::InvalidChange,
}
}
}
impl<T: GraphTxnT + TreeTxnT> From<crate::pristine::InconsistentChange<T::GraphError>>
for LocalApplyError<T>
{
fn from(err: crate::pristine::InconsistentChange<T::GraphError>) -> Self {
match err {
InconsistentChange::Txn(e) => LocalApplyError::Txn(TxnErr(e)),
_ => LocalApplyError::InvalidChange,
}
}
}
impl<T: GraphTxnT + TreeTxnT> From<crate::pristine::BlockError<T::GraphError>>
for LocalApplyError<T>
{
fn from(err: crate::pristine::BlockError<T::GraphError>) -> Self {
match err {
BlockError::Txn(e) => LocalApplyError::Txn(TxnErr(e)),
Ok(apply_change_to_channel(
txn, channel, internal, &hash, &change, workspace,
)?)
Ok(
apply_change_to_channel(txn, channel, internal, &hash, &change, workspace)
.map_err(ApplyError::LocalChange)?,
)
T: ChannelMutTxnT
+ DepsMutTxnT<DepsError = <T as GraphTxnT>::GraphError>
+ TreeMutTxnT<TreeError = <T as GraphTxnT>::GraphError>,
T: ChannelMutTxnT + DepsMutTxnT<DepsError = <T as GraphTxnT>::GraphError> + TreeMutTxnT,
T: ChannelMutTxnT
+ DepsMutTxnT<DepsError = <T as GraphTxnT>::GraphError>
+ TreeMutTxnT<TreeError = <T as GraphTxnT>::GraphError>,
T: ChannelMutTxnT + DepsMutTxnT<DepsError = <T as GraphTxnT>::GraphError> + TreeMutTxnT,
for &(vertex, edge) in forward.iter() {
let dest = *txn.find_block(channel, edge.dest()).unwrap();
debug!(target:"libpijul::forward", "deleting forward edge {:?} {:?} {:?}", vertex, dest, edge);
del_graph_with_rev(
txn,
channel,
edge.flag(),
vertex,
dest,
edge.introduced_by(),
)?;
for ve in forward.iter() {
let dest = *txn.find_block(channel, ve.e.dest()).unwrap();
debug!(target:"libpijul::forward", "deleting forward edge {:?} {:?} {:?}", ve.v, dest, ve.e);
del_graph_with_rev(txn, channel, ve.e.flag(), ve.v, dest, ve.e.introduced_by())?;
forward: &mut Vec<(Vertex<ChangeId>, SerializedEdge)>,
) -> Result<(), crate::output::FileError<P::Error, T::GraphError>> {
forward: &mut Vec<super::Redundant>,
) -> Result<(), crate::output::FileError<P::Error, T>> {
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]