Skip to content

Commit 1fbb946

Browse files
committed
fix: make sure ordinary capitalized partial names can be found by partial name.
For instance, previously, a ref named `A` could not be found even though `refs/heads/A` existed.
1 parent ba7b811 commit 1fbb946

33 files changed

+93
-28
lines changed

gix-ref/src/name.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,21 @@ impl PartialNameRef {
6262
}
6363

6464
impl PartialNameRef {
65-
pub(crate) fn looks_like_full_name(&self) -> bool {
65+
pub(crate) fn looks_like_full_name(&self, consider_pseudo_ref: bool) -> bool {
6666
let name = self.0.as_bstr();
6767
name.starts_with_str("refs/")
6868
|| name.starts_with(Category::MainPseudoRef.prefix())
6969
|| name.starts_with(Category::LinkedPseudoRef { name: "".into() }.prefix())
70-
|| is_pseudo_ref(name)
70+
|| (consider_pseudo_ref && is_pseudo_ref(name))
7171
}
72-
pub(crate) fn construct_full_name_ref<'buf>(&self, inbetween: &str, buf: &'buf mut BString) -> &'buf FullNameRef {
72+
pub(crate) fn construct_full_name_ref<'buf>(
73+
&self,
74+
inbetween: &str,
75+
buf: &'buf mut BString,
76+
consider_pseudo_ref: bool,
77+
) -> &'buf FullNameRef {
7378
buf.clear();
74-
if !self.looks_like_full_name() {
79+
if !self.looks_like_full_name(consider_pseudo_ref) {
7580
buf.push_str("refs/");
7681
}
7782
if !inbetween.is_empty() {

gix-ref/src/store/file/find.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::{
66

77
pub use error::Error;
88

9+
use crate::name::is_pseudo_ref;
910
use crate::{
1011
file,
1112
store_impl::{file::loose, packed},
@@ -103,13 +104,28 @@ impl file::Store {
103104
let precomposed_partial_name = precomposed_partial_name_storage
104105
.as_ref()
105106
.map(std::convert::AsRef::as_ref);
106-
for inbetween in &["", "tags", "heads", "remotes"] {
107-
match self.find_inner(inbetween, partial_name, precomposed_partial_name, packed, &mut buf) {
108-
Ok(Some(r)) => return Ok(Some(decompose_if(r, precomposed_partial_name.is_some()))),
109-
Ok(None) => {
110-
continue;
107+
for consider_pseudo_ref in [true, false] {
108+
if !consider_pseudo_ref && !is_pseudo_ref(partial_name.as_bstr()) {
109+
break;
110+
}
111+
'try_directories: for inbetween in &["", "tags", "heads", "remotes"] {
112+
match self.find_inner(
113+
inbetween,
114+
partial_name,
115+
precomposed_partial_name,
116+
packed,
117+
&mut buf,
118+
consider_pseudo_ref,
119+
) {
120+
Ok(Some(r)) => return Ok(Some(decompose_if(r, precomposed_partial_name.is_some()))),
121+
Ok(None) => {
122+
if consider_pseudo_ref && is_pseudo_ref(partial_name.as_bstr()) {
123+
break 'try_directories;
124+
}
125+
continue;
126+
}
127+
Err(err) => return Err(err),
111128
}
112-
Err(err) => return Err(err),
113129
}
114130
}
115131
if partial_name.as_bstr() != "HEAD" {
@@ -129,6 +145,7 @@ impl file::Store {
129145
.map(std::convert::AsRef::as_ref),
130146
None,
131147
&mut buf,
148+
true, /* consider-pseudo-ref */
132149
)
133150
.map(|res| res.map(|r| decompose_if(r, precomposed_partial_name_storage.is_some())))
134151
} else {
@@ -143,10 +160,11 @@ impl file::Store {
143160
precomposed_partial_name: Option<&PartialNameRef>,
144161
packed: Option<&packed::Buffer>,
145162
path_buf: &mut BString,
163+
consider_pseudo_ref: bool,
146164
) -> Result<Option<Reference>, Error> {
147165
let full_name = precomposed_partial_name
148166
.unwrap_or(partial_name)
149-
.construct_full_name_ref(inbetween, path_buf);
167+
.construct_full_name_ref(inbetween, path_buf, consider_pseudo_ref);
150168
let content_buf = self.ref_contents(full_name).map_err(|err| Error::ReadFileContents {
151169
source: err,
152170
path: self.reference_path(full_name),

gix-ref/src/store/packed/find.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ impl packed::Buffer {
1717
let name = name.try_into()?;
1818
let mut buf = BString::default();
1919
for inbetween in &["", "tags", "heads", "remotes"] {
20-
let (name, was_absolute) = if name.looks_like_full_name() {
20+
let (name, was_absolute) = if name.looks_like_full_name(false) {
2121
let name = FullNameRef::new_unchecked(name.as_bstr());
2222
let name = match transform_full_name_for_lookup(name) {
2323
None => return Ok(None),
2424
Some(name) => name,
2525
};
2626
(name, true)
2727
} else {
28-
let full_name = name.construct_full_name_ref(inbetween, &mut buf);
28+
let full_name = name.construct_full_name_ref(inbetween, &mut buf, false);
2929
(full_name, false)
3030
};
3131
match self.try_find_full_name(name)? {

gix-ref/tests/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ serde = ["gix-ref/serde"]
1717

1818
[[test]]
1919
name = "refs"
20-
path = "refs.rs"
20+
path = "refs/main.rs"
2121

2222
[dev-dependencies]
2323
gix-ref = { path = ".." }
Binary file not shown.
Binary file not shown.

gix-ref/tests/fixtures/make_packed_ref_repository.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ git checkout -q -b main
77
git commit -q --allow-empty -m c1
88
git branch dt1
99
git branch d1
10+
git branch A
1011

1112
mkdir -p .git/refs/remotes/origin
1213

gix-ref/tests/fixtures/make_packed_ref_repository_for_overlay.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ git init -q
66
git checkout -q -b main
77
git commit -q --allow-empty -m c1
88
git branch newer-as-loose
9+
git branch A
910
git tag -m "tag object" tag-object
1011

1112
mkdir -p .git/refs/remotes/origin

gix-ref/tests/fixtures/make_ref_repository.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ git checkout -q -b main
77
git commit -q --allow-empty -m c1
88
git branch dt1
99
git branch d1
10+
git branch A
1011

1112
mkdir -p .git/refs/remotes/origin
1213

0 commit comments

Comments
 (0)