Unified · Split
| @@ -182,6 +182,7 @@ pub(in crate::command::release_impl) fn create_version_tag( · 181 unmodified lines | ||
| 182 | 182 | } |
| 183 | 183 | Ok(Some(edit.name)) |
| 184 | 184 | } else { |
| 185 | + // ctx.git_easy.edit_reference(Some(refedit), lockmode) | |
| 185 | 186 | let edits = ctx |
| 186 | 187 | .git_easy |
| 187 | 188 | .repo |
| @@ -116,7 +116,10 @@ impl packed::Transaction { · 115 unmodified lines | ||
| 116 | 116 | Ok(self) |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | − /// Commit the prepare transaction | |
| 119 | + /// Commit the prepared transaction. | |
| 120 | + /// | |
| 121 | + /// Please note that actual edits invalidated existing packed buffers. | |
| 122 | + /// Note: There is the potential to write changes into memory and return such a packed-refs buffer for reuse. | |
| 120 | 123 | pub fn commit(self) -> Result<(), commit::Error> { |
| 121 | 124 | let mut edits = self.edits.expect("BUG: cannot call commit() before prepare(…)"); |
| 122 | 125 | if edits.is_empty() { |
| @@ -1,227 +0,0 @@ | ||
| 1 | −mod tree { | |
| 2 | − #[cfg(feature = "git-diff")] | |
| 3 | − use std::borrow::BorrowMut; | |
| 4 | − | |
| 5 | − #[cfg(feature = "git-diff")] | |
| 6 | − use git_hash::oid; | |
| 7 | − use git_object::immutable; | |
| 8 | − #[cfg(feature = "git-traverse")] | |
| 9 | − use git_traverse::tree::breadthfirst; | |
| 10 | − | |
| 11 | − pub trait Sealed {} | |
| 12 | − | |
| 13 | − pub trait TreeIterExt: Sealed { | |
| 14 | − #[cfg(feature = "git-diff")] | |
| 15 | − fn changes_needed<FindFn, R, StateMut>( | |
| 16 | − &self, | |
| 17 | − other: immutable::TreeIter<'_>, | |
| 18 | − state: StateMut, | |
| 19 | − find: FindFn, | |
| 20 | − delegate: &mut R, | |
| 21 | − ) -> Result<(), git_diff::tree::changes::Error> | |
| 22 | − where | |
| 23 | − FindFn: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Option<immutable::tree::TreeIter<'b>>, | |
| 24 | − R: git_diff::tree::Visit, | |
| 25 | − StateMut: BorrowMut<git_diff::tree::State>; | |
| 26 | − | |
| 27 | − /// Use this for squeezing out the last bits of performance. | |
| 28 | − #[cfg(feature = "git-traverse")] | |
| 29 | − fn traverse<StateMut, Find, V>( | |
| 30 | − &self, | |
| 31 | − state: StateMut, | |
| 32 | − find: Find, | |
| 33 | − delegate: &mut V, | |
| 34 | − ) -> Result<(), breadthfirst::Error> | |
| 35 | − where | |
| 36 | − Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Option<immutable::TreeIter<'a>>, | |
| 37 | − StateMut: BorrowMut<breadthfirst::State>, | |
| 38 | − V: git_traverse::tree::Visit; | |
| 39 | − } | |
| 40 | − | |
| 41 | − impl<'d> Sealed for immutable::TreeIter<'d> {} | |
| 42 | − | |
| 43 | − impl<'d> TreeIterExt for immutable::TreeIter<'d> { | |
| 44 | − #[cfg(feature = "git-diff")] | |
| 45 | − fn changes_needed<FindFn, R, StateMut>( | |
| 46 | − &self, | |
| 47 | − other: immutable::TreeIter<'_>, | |
| 48 | − state: StateMut, | |
| 49 | − find: FindFn, | |
| 50 | − delegate: &mut R, | |
| 51 | − ) -> Result<(), git_diff::tree::changes::Error> | |
| 52 | − where | |
| 53 | − FindFn: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Option<immutable::tree::TreeIter<'b>>, | |
| 54 | − R: git_diff::tree::Visit, | |
| 55 | − StateMut: BorrowMut<git_diff::tree::State>, | |
| 56 | − { | |
| 57 | − git_diff::tree::Changes::from(Some(self.clone())).needed_to_obtain(other, state, find, delegate) | |
| 58 | − } | |
| 59 | − | |
| 60 | − #[cfg(feature = "git-traverse")] | |
| 61 | − fn traverse<StateMut, Find, V>( | |
| 62 | − &self, | |
| 63 | − state: StateMut, | |
| 64 | − find: Find, | |
| 65 | − delegate: &mut V, | |
| 66 | − ) -> Result<(), breadthfirst::Error> | |
| 67 | − where | |
| 68 | − Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Option<immutable::TreeIter<'a>>, | |
| 69 | − StateMut: BorrowMut<breadthfirst::State>, | |
| 70 | − V: git_traverse::tree::Visit, | |
| 71 | − { | |
| 72 | − breadthfirst(self.clone(), state, find, delegate) | |
| 73 | − } | |
| 74 | − } | |
| 75 | −} | |
| 76 | −pub use tree::TreeIterExt; | |
| 77 | − | |
| 78 | −mod object_id { | |
| 79 | − use git_hash::ObjectId; | |
| 80 | − #[cfg(feature = "git-traverse")] | |
| 81 | − use git_object::immutable; | |
| 82 | − #[cfg(feature = "git-traverse")] | |
| 83 | − use git_traverse::commit::ancestors::{Ancestors, State}; | |
| 84 | − | |
| 85 | − use crate::{Access, Oid}; | |
| 86 | − | |
| 87 | − pub trait Sealed {} | |
| 88 | − | |
| 89 | − pub trait ObjectIdExt: Sealed { | |
| 90 | − #[cfg(feature = "git-traverse")] | |
| 91 | − fn ancestors_iter<Find>(self, find: Find) -> Ancestors<Find, fn(&git_hash::oid) -> bool, State> | |
| 92 | − where | |
| 93 | − Find: for<'a> FnMut(&git_hash::oid, &'a mut Vec<u8>) -> Option<immutable::CommitIter<'a>>; | |
| 94 | − | |
| 95 | − fn attach<A: Access + Sized>(self, access: &A) -> Oid<'_, A>; | |
| 96 | − } | |
| 97 | − | |
| 98 | − impl Sealed for ObjectId {} | |
| 99 | − impl ObjectIdExt for ObjectId { | |
| 100 | − #[cfg(feature = "git-traverse")] | |
| 101 | − fn ancestors_iter<Find>(self, find: Find) -> Ancestors<Find, fn(&git_hash::oid) -> bool, State> | |
| 102 | − where | |
| 103 | − Find: for<'a> FnMut(&git_hash::oid, &'a mut Vec<u8>) -> Option<immutable::CommitIter<'a>>, | |
| 104 | − { | |
| 105 | − Ancestors::new(Some(self), State::default(), find) | |
| 106 | − } | |
| 107 | − | |
| 108 | − fn attach<A: Access + Sized>(self, access: &A) -> Oid<'_, A> { | |
| 109 | − Oid::from_id(self, access) | |
| 110 | − } | |
| 111 | − } | |
| 112 | −} | |
| 113 | −pub use object_id::ObjectIdExt; | |
| 114 | − | |
| 115 | −pub(crate) mod access { | |
| 116 | − pub(crate) mod object { | |
| 117 | − use std::ops::DerefMut; | |
| 118 | − | |
| 119 | − use git_hash::ObjectId; | |
| 120 | − | |
| 121 | − use crate::{ | |
| 122 | − object, | |
| 123 | − odb::{Find, FindExt}, | |
| 124 | − Access, ObjectRef, | |
| 125 | − }; | |
| 126 | − | |
| 127 | − pub fn find_object<A: Access + Sized>( | |
| 128 | − access: &A, | |
| 129 | − id: impl Into<ObjectId>, | |
| 130 | − ) -> Result<ObjectRef<'_, A>, object::find::existing::Error> { | |
| 131 | − let cache = access.cache(); | |
| 132 | − let id = id.into(); | |
| 133 | − let kind = { | |
| 134 | − let mut buf = access.cache().buf.borrow_mut(); | |
| 135 | − let obj = access | |
| 136 | − .repo() | |
| 137 | − .odb | |
| 138 | − .find_existing(&id, &mut buf, cache.pack.borrow_mut().deref_mut())?; | |
| 139 | − obj.kind | |
| 140 | − }; | |
| 141 | − | |
| 142 | − Ok(ObjectRef::from_current_buf(id, kind, access)) | |
| 143 | − } | |
| 144 | − | |
| 145 | − pub fn try_find_object<A: Access + Sized>( | |
| 146 | − access: &A, | |
| 147 | − id: impl Into<ObjectId>, | |
| 148 | − ) -> Result<Option<ObjectRef<'_, A>>, object::find::Error> { | |
| 149 | − let cache = access.cache(); | |
| 150 | − let id = id.into(); | |
| 151 | − Ok(access | |
| 152 | − .repo() | |
| 153 | − .odb | |
| 154 | − .find(&id, &mut cache.buf.borrow_mut(), cache.pack.borrow_mut().deref_mut())? | |
| 155 | − .map(|obj| { | |
| 156 | − let kind = obj.kind; | |
| 157 | − drop(obj); | |
| 158 | − ObjectRef::from_current_buf(id, kind, access) | |
| 159 | − })) | |
| 160 | − } | |
| 161 | − | |
| 162 | − pub trait ObjectAccessExt: Access + Sized { | |
| 163 | − // NOTE: in order to get the actual kind of object, is must be fully decoded from storage in case of packs | |
| 164 | − // even though partial decoding is possible for loose objects, it won't matter much here. | |
| 165 | − fn find_object( | |
| 166 | − &self, | |
| 167 | − id: impl Into<ObjectId>, | |
| 168 | − ) -> Result<ObjectRef<'_, Self>, object::find::existing::Error> { | |
| 169 | − find_object(self, id) | |
| 170 | − } | |
| 171 | − | |
| 172 | − fn try_find_object( | |
| 173 | − &self, | |
| 174 | − id: impl Into<ObjectId>, | |
| 175 | − ) -> Result<Option<ObjectRef<'_, Self>>, object::find::Error> { | |
| 176 | − try_find_object(self, id) | |
| 177 | − } | |
| 178 | − } | |
| 179 | − } | |
| 180 | − | |
| 181 | − pub(crate) mod reference { | |
| 182 | − use std::convert::TryInto; | |
| 183 | − | |
| 184 | − use crate::{ | |
| 185 | − reference, | |
| 186 | − refs::{file::find::Error, PartialName}, | |
| 187 | − Access, Reference, | |
| 188 | − }; | |
| 189 | − | |
| 190 | − /// Obtain and alter references comfortably | |
| 191 | − pub trait ReferenceAccessExt: Access + Sized { | |
| 192 | − fn find_reference<'a, Name, E>( | |
| 193 | − &self, | |
| 194 | − name: Name, | |
| 195 | − ) -> Result<Reference<'_, Self>, reference::find::existing::Error> | |
| 196 | − where | |
| 197 | − Name: TryInto<PartialName<'a>, Error = E>, | |
| 198 | − Error: From<E>, | |
| 199 | − { | |
| 200 | − self.try_find_reference(name)? | |
| 201 | − .ok_or(reference::find::existing::Error::NotFound) | |
| 202 | − } | |
| 203 | − | |
| 204 | − fn try_find_reference<'a, Name, E>( | |
| 205 | − &self, | |
| 206 | − name: Name, | |
| 207 | − ) -> Result<Option<Reference<'_, Self>>, reference::find::Error> | |
| 208 | − where | |
| 209 | − Name: TryInto<PartialName<'a>, Error = E>, | |
| 210 | − Error: From<E>, | |
| 211 | − { | |
| 212 | − let cache = self.cache(); | |
| 213 | − cache.assure_packed_refs_present(&self.repo().refs)?; | |
| 214 | − match self.repo().refs.find(name, cache.packed_refs.borrow().as_ref()) { | |
| 215 | − Ok(r) => match r { | |
| 216 | − Some(r) => Ok(Some(Reference::from_ref(r, self))), | |
| 217 | − None => Ok(None), | |
| 218 | − }, | |
| 219 | − Err(err) => Err(err.into()), | |
| 220 | − } | |
| 221 | − } | |
| 222 | − } | |
| 223 | − | |
| 224 | − impl<A> ReferenceAccessExt for A where A: Access + Sized {} | |
| 225 | − } | |
| 226 | −} | |
| 227 | −pub use access::{object::ObjectAccessExt, reference::ReferenceAccessExt}; | |
| @@ -0,0 +1,104 @@ | ||
| 1 | +pub(crate) mod object { | |
| 2 | + use std::ops::DerefMut; | |
| 3 | + | |
| 4 | + use git_hash::ObjectId; | |
| 5 | + | |
| 6 | + use crate::{ | |
| 7 | + object, | |
| 8 | + odb::{Find, FindExt}, | |
| 9 | + Access, ObjectRef, | |
| 10 | + }; | |
| 11 | + | |
| 12 | + pub fn find_object<A: Access + Sized>( | |
| 13 | + access: &A, | |
| 14 | + id: impl Into<ObjectId>, | |
| 15 | + ) -> Result<ObjectRef<'_, A>, object::find::existing::Error> { | |
| 16 | + let cache = access.cache(); | |
| 17 | + let id = id.into(); | |
| 18 | + let kind = { | |
| 19 | + let mut buf = access.cache().buf.borrow_mut(); | |
| 20 | + let obj = access | |
| 21 | + .repo() | |
| 22 | + .odb | |
| 23 | + .find_existing(&id, &mut buf, cache.pack.borrow_mut().deref_mut())?; | |
| 24 | + obj.kind | |
| 25 | + }; | |
| 26 | + | |
| 27 | + Ok(ObjectRef::from_current_buf(id, kind, access)) | |
| 28 | + } | |
| 29 | + | |
| 30 | + pub fn try_find_object<A: Access + Sized>( | |
| 31 | + access: &A, | |
| 32 | + id: impl Into<ObjectId>, | |
| 33 | + ) -> Result<Option<ObjectRef<'_, A>>, object::find::Error> { | |
| 34 | + let cache = access.cache(); | |
| 35 | + let id = id.into(); | |
| 36 | + Ok(access | |
| 37 | + .repo() | |
| 38 | + .odb | |
| 39 | + .find(&id, &mut cache.buf.borrow_mut(), cache.pack.borrow_mut().deref_mut())? | |
| 40 | + .map(|obj| { | |
| 41 | + let kind = obj.kind; | |
| 42 | + drop(obj); | |
| 43 | + ObjectRef::from_current_buf(id, kind, access) | |
| 44 | + })) | |
| 45 | + } | |
| 46 | + | |
| 47 | + pub trait ObjectAccessExt: Access + Sized { | |
| 48 | + // NOTE: in order to get the actual kind of object, is must be fully decoded from storage in case of packs | |
| 49 | + // even though partial decoding is possible for loose objects, it won't matter much here. | |
| 50 | + fn find_object(&self, id: impl Into<ObjectId>) -> Result<ObjectRef<'_, Self>, object::find::existing::Error> { | |
| 51 | + find_object(self, id) | |
| 52 | + } | |
| 53 | + | |
| 54 | + fn try_find_object(&self, id: impl Into<ObjectId>) -> Result<Option<ObjectRef<'_, Self>>, object::find::Error> { | |
| 55 | + try_find_object(self, id) | |
| 56 | + } | |
| 57 | + } | |
| 58 | +} | |
| 59 | + | |
| 60 | +pub(crate) mod reference { | |
| 61 | + use std::convert::TryInto; | |
| 62 | + | |
| 63 | + use crate::{ | |
| 64 | + reference, | |
| 65 | + refs::{file::find::Error, PartialName}, | |
| 66 | + Access, Reference, | |
| 67 | + }; | |
| 68 | + | |
| 69 | + /// Obtain and alter references comfortably | |
| 70 | + pub trait ReferenceAccessExt: Access + Sized { | |
| 71 | + fn find_reference<'a, Name, E>( | |
| 72 | + &self, | |
| 73 | + name: Name, | |
| 74 | + ) -> Result<Reference<'_, Self>, reference::find::existing::Error> | |
| 75 | + where | |
| 76 | + Name: TryInto<PartialName<'a>, Error = E>, | |
| 77 | + Error: From<E>, | |
| 78 | + { | |
| 79 | + self.try_find_reference(name)? | |
| 80 | + .ok_or(reference::find::existing::Error::NotFound) | |
| 81 | + } | |
| 82 | + | |
| 83 | + fn try_find_reference<'a, Name, E>( | |
| 84 | + &self, | |
| 85 | + name: Name, | |
| 86 | + ) -> Result<Option<Reference<'_, Self>>, reference::find::Error> | |
| 87 | + where | |
| 88 | + Name: TryInto<PartialName<'a>, Error = E>, | |
| 89 | + Error: From<E>, | |
| 90 | + { | |
| 91 | + let cache = self.cache(); | |
| 92 | + cache.assure_packed_refs_present(&self.repo().refs)?; | |
| 93 | + match self.repo().refs.find(name, cache.packed_refs.borrow().as_ref()) { | |
| 94 | + Ok(r) => match r { | |
| 95 | + Some(r) => Ok(Some(Reference::from_file_ref(r, self))), | |
| 96 | + None => Ok(None), | |
| 97 | + }, | |
| 98 | + Err(err) => Err(err.into()), | |
| 99 | + } | |
| 100 | + } | |
| 101 | + } | |
| 102 | + | |
| 103 | + impl<A> ReferenceAccessExt for A where A: Access + Sized {} | |
| 104 | +} | |
| @@ -0,0 +1,8 @@ | ||
| 1 | +mod tree; | |
| 2 | +pub use tree::TreeIterExt; | |
| 3 | + | |
| 4 | +mod object_id; | |
| 5 | +pub use object_id::ObjectIdExt; | |
| 6 | + | |
| 7 | +pub(crate) mod access; | |
| 8 | +pub use access::{object::ObjectAccessExt, reference::ReferenceAccessExt}; | |
| @@ -0,0 +1,34 @@ | ||
| 1 | +use git_hash::ObjectId; | |
| 2 | +#[cfg(feature = "git-traverse")] | |
| 3 | +use git_object::immutable; | |
| 4 | +#[cfg(feature = "git-traverse")] | |
| 5 | +use git_traverse::commit::ancestors::{Ancestors, State}; | |
| 6 | + | |
| 7 | +use crate::{Access, Oid}; | |
| 8 | + | |
| 9 | +pub trait Sealed {} | |
| 10 | + | |
| 11 | +pub trait ObjectIdExt: Sealed { | |
| 12 | + #[cfg(feature = "git-traverse")] | |
| 13 | + fn ancestors_iter<Find>(self, find: Find) -> Ancestors<Find, fn(&git_hash::oid) -> bool, State> | |
| 14 | + where | |
| 15 | + Find: for<'a> FnMut(&git_hash::oid, &'a mut Vec<u8>) -> Option<immutable::CommitIter<'a>>; | |
| 16 | + | |
| 17 | + fn attach<A: Access + Sized>(self, access: &A) -> Oid<'_, A>; | |
| 18 | +} | |
| 19 | + | |
| 20 | +impl Sealed for ObjectId {} | |
| 21 | + | |
| 22 | +impl ObjectIdExt for ObjectId { | |
| 23 | + #[cfg(feature = "git-traverse")] | |
| 24 | + fn ancestors_iter<Find>(self, find: Find) -> Ancestors<Find, fn(&git_hash::oid) -> bool, State> | |
| 25 | + where | |
| 26 | + Find: for<'a> FnMut(&git_hash::oid, &'a mut Vec<u8>) -> Option<immutable::CommitIter<'a>>, | |
| 27 | + { | |
| 28 | + Ancestors::new(Some(self), State::default(), find) | |
| 29 | + } | |
| 30 | + | |
| 31 | + fn attach<A: Access + Sized>(self, access: &A) -> Oid<'_, A> { | |
| 32 | + Oid::from_id(self, access) | |
| 33 | + } | |
| 34 | +} | |
| @@ -0,0 +1,73 @@ | ||
| 1 | +#[cfg(feature = "git-diff")] | |
| 2 | +use std::borrow::BorrowMut; | |
| 3 | + | |
| 4 | +#[cfg(feature = "git-diff")] | |
| 5 | +use git_hash::oid; | |
| 6 | +use git_object::immutable; | |
| 7 | +#[cfg(feature = "git-traverse")] | |
| 8 | +use git_traverse::tree::breadthfirst; | |
| 9 | + | |
| 10 | +pub trait Sealed {} | |
| 11 | + | |
| 12 | +pub trait TreeIterExt: Sealed { | |
| 13 | + #[cfg(feature = "git-diff")] | |
| 14 | + fn changes_needed<FindFn, R, StateMut>( | |
| 15 | + &self, | |
| 16 | + other: immutable::TreeIter<'_>, | |
| 17 | + state: StateMut, | |
| 18 | + find: FindFn, | |
| 19 | + delegate: &mut R, | |
| 20 | + ) -> Result<(), git_diff::tree::changes::Error> | |
| 21 | + where | |
| 22 | + FindFn: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Option<immutable::tree::TreeIter<'b>>, | |
| 23 | + R: git_diff::tree::Visit, | |
| 24 | + StateMut: BorrowMut<git_diff::tree::State>; | |
| 25 | + | |
| 26 | + /// Use this for squeezing out the last bits of performance. | |
| 27 | + #[cfg(feature = "git-traverse")] | |
| 28 | + fn traverse<StateMut, Find, V>( | |
| 29 | + &self, | |
| 30 | + state: StateMut, | |
| 31 | + find: Find, | |
| 32 | + delegate: &mut V, | |
| 33 | + ) -> Result<(), breadthfirst::Error> | |
| 34 | + where | |
| 35 | + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Option<immutable::TreeIter<'a>>, | |
| 36 | + StateMut: BorrowMut<breadthfirst::State>, | |
| 37 | + V: git_traverse::tree::Visit; | |
| 38 | +} | |
| 39 | + | |
| 40 | +impl<'d> Sealed for immutable::TreeIter<'d> {} | |
| 41 | + | |
| 42 | +impl<'d> TreeIterExt for immutable::TreeIter<'d> { | |
| 43 | + #[cfg(feature = "git-diff")] | |
| 44 | + fn changes_needed<FindFn, R, StateMut>( | |
| 45 | + &self, | |
| 46 | + other: immutable::TreeIter<'_>, | |
| 47 | + state: StateMut, | |
| 48 | + find: FindFn, | |
| 49 | + delegate: &mut R, | |
| 50 | + ) -> Result<(), git_diff::tree::changes::Error> | |
| 51 | + where | |
| 52 | + FindFn: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Option<immutable::tree::TreeIter<'b>>, | |
| 53 | + R: git_diff::tree::Visit, | |
| 54 | + StateMut: BorrowMut<git_diff::tree::State>, | |
| 55 | + { | |
| 56 | + git_diff::tree::Changes::from(Some(self.clone())).needed_to_obtain(other, state, find, delegate) | |
| 57 | + } | |
| 58 | + | |
| 59 | + #[cfg(feature = "git-traverse")] | |
| 60 | + fn traverse<StateMut, Find, V>( | |
| 61 | + &self, | |
| 62 | + state: StateMut, | |
| 63 | + find: Find, | |
| 64 | + delegate: &mut V, | |
| 65 | + ) -> Result<(), breadthfirst::Error> | |
| 66 | + where | |
| 67 | + Find: for<'a> FnMut(&oid, &'a mut Vec<u8>) -> Option<immutable::TreeIter<'a>>, | |
| 68 | + StateMut: BorrowMut<breadthfirst::State>, | |
| 69 | + V: git_traverse::tree::Visit, | |
| 70 | + { | |
| 71 | + breadthfirst(self.clone(), state, find, delegate) | |
| 72 | + } | |
| 73 | +} | |
| @@ -50,7 +50,7 @@ impl<'repo, A> Reference<'repo, A> · 49 unmodified lines | ||
| 50 | 50 | where |
| 51 | 51 | A: Access + Sized, |
| 52 | 52 | { |
| 53 | − pub(crate) fn from_ref(reference: refs::file::Reference<'_>, access: &'repo A) -> Self { | |
| 53 | + pub(crate) fn from_file_ref(reference: refs::file::Reference<'_>, access: &'repo A) -> Self { | |
| 54 | 54 | Reference { |
| 55 | 55 | backing: match reference { |
| 56 | 56 | refs::file::Reference::Packed(p) => Backing::OwnedPacked { |