Skip to content

Commit 3fa52f8

Browse files
committed
and the entire test-suite passes (#450)
1 parent d7c2789 commit 3fa52f8

File tree

4 files changed

+89
-7
lines changed

4 files changed

+89
-7
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

git-refspec/Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ doctest = false
1414
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1515

1616
[dependencies]
17-
bstr = { version = "0.2.13", default-features = false, features = ["std"]}
17+
git-revision = { version = "^0.3.0", path = "../git-revision" }
1818
git-validate = { version = "^0.5.4", path = "../git-validate" }
19+
git-hash = { version = "^0.9.6", path = "../git-hash" }
20+
21+
bstr = { version = "0.2.13", default-features = false, features = ["std"]}
1922
thiserror = "1.0.26"
2023
smallvec = "1.9.0"
2124

git-refspec/src/parse.rs

+83-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ pub enum Error {
1111
#[error("Both sides of the specification need a pattern, like 'a/*:b/*'")]
1212
PatternUnbalanced,
1313
#[error(transparent)]
14-
Refname(#[from] git_validate::refname::Error),
14+
ReferenceName(#[from] git_validate::refname::Error),
15+
#[error(transparent)]
16+
RevSpec(#[from] git_revision::spec::parse::Error),
1517
}
1618

1719
pub(crate) mod function {
@@ -84,8 +86,8 @@ pub(crate) mod function {
8486
}
8587
};
8688

87-
let (src, src_had_pattern) = validated(src)?;
88-
let (dst, dst_had_pattern) = validated(dst)?;
89+
let (src, src_had_pattern) = validated(src, operation == Operation::Push)?;
90+
let (dst, dst_had_pattern) = validated(dst, false)?;
8991
if mode != Mode::Negative && src_had_pattern != dst_had_pattern {
9092
return Err(Error::PatternUnbalanced);
9193
}
@@ -97,7 +99,7 @@ pub(crate) mod function {
9799
})
98100
}
99101

100-
fn validated(spec: Option<&BStr>) -> Result<(Option<&BStr>, bool), Error> {
102+
fn validated(spec: Option<&BStr>, allow_revspecs: bool) -> Result<(Option<&BStr>, bool), Error> {
101103
match spec {
102104
Some(spec) => {
103105
let glob_count = spec.iter().filter(|b| **b == b'*').take(2).count();
@@ -111,11 +113,87 @@ pub(crate) mod function {
111113
buf[glob_pos] = b'a';
112114
git_validate::reference::name_partial(buf.as_bstr())?;
113115
} else {
114-
git_validate::reference::name_partial(spec)?;
116+
git_validate::reference::name_partial(spec)
117+
.map_err(Error::from)
118+
.or_else(|err| {
119+
if allow_revspecs {
120+
match git_revision::spec::parse(spec, &mut super::revparse::Noop) {
121+
Ok(_) => {
122+
if spec.iter().any(|b| b.is_ascii_whitespace()) {
123+
Err(err)
124+
} else {
125+
Ok(spec)
126+
}
127+
}
128+
Err(err) => Err(err.into()),
129+
}
130+
} else {
131+
Err(err)
132+
}
133+
})?;
115134
}
116135
Ok((Some(spec), glob_count == 1))
117136
}
118137
None => Ok((None, false)),
119138
}
120139
}
121140
}
141+
142+
mod revparse {
143+
use bstr::BStr;
144+
use git_revision::spec::parse::delegate::{
145+
Kind, Navigate, PeelTo, PrefixHint, ReflogLookup, Revision, SiblingBranch, Traversal,
146+
};
147+
148+
pub(crate) struct Noop;
149+
150+
impl Revision for Noop {
151+
fn find_ref(&mut self, _name: &BStr) -> Option<()> {
152+
Some(())
153+
}
154+
155+
fn disambiguate_prefix(&mut self, _prefix: git_hash::Prefix, _hint: Option<PrefixHint<'_>>) -> Option<()> {
156+
Some(())
157+
}
158+
159+
fn reflog(&mut self, _query: ReflogLookup) -> Option<()> {
160+
Some(())
161+
}
162+
163+
fn nth_checked_out_branch(&mut self, _branch_no: usize) -> Option<()> {
164+
Some(())
165+
}
166+
167+
fn sibling_branch(&mut self, _kind: SiblingBranch) -> Option<()> {
168+
Some(())
169+
}
170+
}
171+
172+
impl Navigate for Noop {
173+
fn traverse(&mut self, _kind: Traversal) -> Option<()> {
174+
Some(())
175+
}
176+
177+
fn peel_until(&mut self, _kind: PeelTo<'_>) -> Option<()> {
178+
Some(())
179+
}
180+
181+
fn find(&mut self, _regex: &BStr, _negated: bool) -> Option<()> {
182+
Some(())
183+
}
184+
185+
fn index_lookup(&mut self, _path: &BStr, _stage: u8) -> Option<()> {
186+
Some(())
187+
}
188+
}
189+
190+
impl Kind for Noop {
191+
fn kind(&mut self, _kind: git_revision::spec::Kind) -> Option<()> {
192+
Some(())
193+
}
194+
}
195+
196+
impl git_revision::spec::parse::Delegate for Noop {
197+
fn done(&mut self) {}
198+
}
199+
}

git-refspec/tests/parse/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use git_testtools::scripted_fixture_repo_read_only;
44
use std::panic::catch_unwind;
55

66
#[test]
7-
#[should_panic]
87
fn baseline() {
98
let dir = scripted_fixture_repo_read_only("make_baseline.sh").unwrap();
109
let baseline = std::fs::read(dir.join("baseline.git")).unwrap();

0 commit comments

Comments
 (0)