History

fix!: Don't degenerate errors when accessing objects

Sebastian Thiel committed 4 years ago

Commit 6d9533d1 parent 867fc202 files · +29 −15Browse files

Showing the changes to git-diff/src (1 of 2 files). Show all

Unified · Split

git-diff/src/tree/changes.rs+23−7
@@ -12,7 +12,10 @@ use crate::{ · 11 unmodified lines
12#[allow(missing_docs)]12#[allow(missing_docs)]
13pub enum Error {13pub enum Error {
14 #[error("The object {oid} referenced by the tree or the tree itself was not found in the database")]14 #[error("The object {oid} referenced by the tree or the tree itself was not found in the database")]
15 NotFound { oid: ObjectId },15 FindExisting {
16 oid: ObjectId,
17 source: Box<dyn std::error::Error + Send + Sync + 'static>,
18 },
16 #[error("The delegate cancelled the operation")]19 #[error("The delegate cancelled the operation")]
17 Cancelled,20 Cancelled,
18 #[error(transparent)]21 #[error(transparent)]
@@ -43,7 +46,7 @@ impl<'a> tree::Changes<'a> { · 24 unmodified lines
43 ///46 ///
44 /// [git_cmp_c]: https://github.com/git/git/blob/311531c9de557d25ac087c1637818bd2aad6eb3a/tree-diff.c#L49:L6547 /// [git_cmp_c]: https://github.com/git/git/blob/311531c9de557d25ac087c1637818bd2aad6eb3a/tree-diff.c#L49:L65
45 /// [git_cmp_rs]: https://github.com/Byron/gitoxide/blob/a4d5f99c8dc99bf814790928a3bf9649cd99486b/git-object/src/mutable/tree.rs#L52-L5548 /// [git_cmp_rs]: https://github.com/Byron/gitoxide/blob/a4d5f99c8dc99bf814790928a3bf9649cd99486b/git-object/src/mutable/tree.rs#L52-L55
46 pub fn needed_to_obtain<FindFn, R, StateMut>(49 pub fn needed_to_obtain<FindFn, R, StateMut, E>(
47 mut self,50 mut self,
48 other: git_object::TreeRefIter<'_>,51 other: git_object::TreeRefIter<'_>,
49 mut state: StateMut,52 mut state: StateMut,
@@ -51,7 +54,8 @@ impl<'a> tree::Changes<'a> { · 1 unmodified line
51 delegate: &mut R,54 delegate: &mut R,
52 ) -> Result<(), Error>55 ) -> Result<(), Error>
53 where56 where
54 FindFn: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Option<git_object::TreeRefIter<'b>>,57 FindFn: for<'b> FnMut(&oid, &'b mut Vec<u8>) -> Result<git_object::TreeRefIter<'b>, E>,
58 E: std::error::Error + Send + Sync + 'static,
55 R: tree::Visit,59 R: tree::Visit,
56 StateMut: BorrowMut<tree::State>,60 StateMut: BorrowMut<tree::State>,
57 {61 {
@@ -72,16 +76,28 @@ impl<'a> tree::Changes<'a> { · 14 unmodified lines
72 match state.trees.pop_front() {76 match state.trees.pop_front() {
73 Some((None, Some(rhs))) => {77 Some((None, Some(rhs))) => {
74 delegate.pop_front_tracked_path_and_set_current();78 delegate.pop_front_tracked_path_and_set_current();
75 rhs_entries = peekable(find(&rhs, &mut state.buf2).ok_or(Error::NotFound { oid: rhs })?);79 rhs_entries = peekable(find(&rhs, &mut state.buf2).map_err(|err| Error::FindExisting {
80 oid: rhs,
81 source: err.into(),
82 })?);
76 }83 }
77 Some((Some(lhs), Some(rhs))) => {84 Some((Some(lhs), Some(rhs))) => {
78 delegate.pop_front_tracked_path_and_set_current();85 delegate.pop_front_tracked_path_and_set_current();
79 lhs_entries = peekable(find(&lhs, &mut state.buf1).ok_or(Error::NotFound { oid: lhs })?);86 lhs_entries = peekable(find(&lhs, &mut state.buf1).map_err(|err| Error::FindExisting {
80 rhs_entries = peekable(find(&rhs, &mut state.buf2).ok_or(Error::NotFound { oid: rhs })?);87 oid: lhs,
88 source: err.into(),
89 })?);
90 rhs_entries = peekable(find(&rhs, &mut state.buf2).map_err(|err| Error::FindExisting {
91 oid: rhs,
92 source: err.into(),
93 })?);
81 }94 }
82 Some((Some(lhs), None)) => {95 Some((Some(lhs), None)) => {
83 delegate.pop_front_tracked_path_and_set_current();96 delegate.pop_front_tracked_path_and_set_current();
84 lhs_entries = peekable(find(&lhs, &mut state.buf1).ok_or(Error::NotFound { oid: lhs })?);97 lhs_entries = peekable(find(&lhs, &mut state.buf1).map_err(|err| Error::FindExisting {
98 oid: lhs,
99 source: err.into(),
100 })?);
85 }101 }
86 Some((None, None)) => unreachable!("BUG: it makes no sense to fill the stack with empties"),102 Some((None, None)) => unreachable!("BUG: it makes no sense to fill the stack with empties"),
87 None => return Ok(()),103 None => return Ok(()),