Unified · Split
| @@ -25,7 +25,13 @@ impl delegate::Navigate for Delegate<'_> { · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | let mut replacements = Replacements::default(); |
| 27 | 27 | let mut errors = Vec::new(); |
| 28 | − let objs = self.objs[self.idx].as_mut()?; | |
| 28 | + let objs = match self.objs[self.idx].as_mut() { | |
| 29 | + Some(objs) => objs, | |
| 30 | + None => { | |
| 31 | + self.err.push(Error::TraversalWithoutStartObject); | |
| 32 | + return None; | |
| 33 | + } | |
| 34 | + }; | |
| 29 | 35 | let repo = self.repo; |
| 30 | 36 | |
| 31 | 37 | for obj in objs.iter() { |
| @@ -105,7 +105,6 @@ impl Error { · 104 unmodified lines | ||
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | pub(crate) fn from_errors(errors: Vec<Self>) -> Self { |
| 108 | − assert!(!errors.is_empty()); | |
| 109 | 108 | match errors.len() { |
| 110 | 109 | 0 => unreachable!( |
| 111 | 110 | "BUG: cannot create something from nothing, must have recorded some errors to call from_errors()" |
| @@ -188,6 +188,8 @@ pub enum Error { · 187 unmodified lines | ||
| 188 | 188 | }, |
| 189 | 189 | #[error(transparent)] |
| 190 | 190 | Traverse(#[from] crate::revision::walk::iter::Error), |
| 191 | + #[error("Tried to navigate the commit-graph without providing an anchor first")] | |
| 192 | + TraversalWithoutStartObject, | |
| 191 | 193 | #[error(transparent)] |
| 192 | 194 | Walk(#[from] crate::revision::walk::Error), |
| 193 | 195 | #[error("Spec does not contain a single object id")] |
Binary file not shown.
| @@ -356,6 +356,7 @@ EOF · 355 unmodified lines | ||
| 356 | 356 | baseline "@^{/!-B}" # negation from branch |
| 357 | 357 | baseline ":file" # index lookup, default stage 0 |
| 358 | 358 | baseline ":1:file" # stage 1 |
| 359 | + baseline ":5:file" # invalid stage | |
| 359 | 360 | baseline ":foo" # not found |
| 360 | 361 | # parents |
| 361 | 362 | baseline "a" |
| @@ -381,6 +382,10 @@ EOF · 19 unmodified lines | ||
| 381 | 382 | baseline "b^3^2" |
| 382 | 383 | baseline "a^^3^2" |
| 383 | 384 | |
| 385 | + # invalid | |
| 386 | + baseline "^^" | |
| 387 | + baseline "^^HEAD" | |
| 388 | + | |
| 384 | 389 | baseline "@{-1}" |
| 385 | 390 | baseline "@{-2}" |
| 386 | 391 | baseline "@{-3}" |
| @@ -64,6 +64,12 @@ mod index { · 63 unmodified lines | ||
| 64 | 64 | "Path \"file\" did not exist in index at stage 1. It does exist at stage 0. It exists on disk", |
| 65 | 65 | ); |
| 66 | 66 | |
| 67 | + assert_eq!( | |
| 68 | + parse_spec(":5:file", &repo).unwrap_err().to_string(), | |
| 69 | + "Path \"5:file\" did not exist in index at stage 0. It does not exist on disk", | |
| 70 | + "invalid stage ids are interpreted as part of the filename" | |
| 71 | + ); | |
| 72 | + | |
| 67 | 73 | assert_eq!( |
| 68 | 74 | parse_spec(":foo", &repo).unwrap_err().to_string(), |
| 69 | 75 | "Path \"foo\" did not exist in index at stage 0. It does not exist on disk", |
| @@ -24,8 +24,16 @@ fn complex() -> crate::Result { · 23 unmodified lines | ||
| 24 | 24 | #[test] |
| 25 | 25 | fn freestanding_negation_yields_descriptive_error() -> crate::Result { |
| 26 | 26 | let repo = repo("complex_graph")?; |
| 27 | − let expected = "The rev-spec is malformed and misses a ref name"; | |
| 28 | − assert_eq!(parse_spec("^", &repo).unwrap_err().to_string(), expected); | |
| 27 | + for revspec in ["^^", "^^HEAD"] { | |
| 28 | + assert_eq!( | |
| 29 | + parse_spec(revspec, &repo).unwrap_err().to_string(), | |
| 30 | + "Tried to navigate the commit-graph without providing an anchor first" | |
| 31 | + ); | |
| 32 | + } | |
| 33 | + assert_eq!( | |
| 34 | + parse_spec("^", &repo).unwrap_err().to_string(), | |
| 35 | + "The rev-spec is malformed and misses a ref name" | |
| 36 | + ); | |
| 29 | 37 | assert_eq!( |
| 30 | 38 | parse_spec("^!", &repo).unwrap_err().to_string(), |
| 31 | 39 | "The ref partially named \"!\" could not be found" |