Skip to content

Commit 2a5ba48

Browse files
committed
ref-format: Relax first component of namespaced
The [manual page](man:gitnamespaces(7)) says: > Git supports dividing the refs of a single repository into > multiple namespaces, each of which has its own branches, > tags, and `HEAD`. Here, the mention of `HEAD` implies that requiring all namespaced to start with refs/namespaces/*/refs is too strict, as there are legal namespaced refs such as refs/namespaces/*/HEAD which are not captured. Relax the corresponding condition, change documentation and add a test to avoid regression.
1 parent 786248a commit 2a5ba48

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

radicle-git-ext/git-ref-format/core/src/deriv.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,11 @@ impl Display for Qualified<'_> {
266266

267267
/// A [`Qualified`] ref under a git namespace.
268268
///
269-
/// A ref is namespaced if it starts with "refs/namespaces/", another path
270-
/// component, and "refs/". Eg.
269+
/// A ref is namespaced if it starts with "refs/namespaces/", and
270+
/// another path component. Eg.
271271
///
272272
/// refs/namespaces/xyz/refs/heads/main
273+
/// refs/namespaces/xyz/HEAD
273274
///
274275
/// Note that namespaces can be nested, so the result of
275276
/// [`Namespaced::strip_namespace`] may be convertible to a [`Namespaced`]
@@ -365,7 +366,7 @@ impl<'a> From<&'a RefStr> for Option<Namespaced<'a>> {
365366
fn from(rs: &'a RefStr) -> Self {
366367
let mut cs = rs.iter();
367368
match (cs.next()?, cs.next()?, cs.next()?, cs.next()?) {
368-
("refs", "namespaces", _, "refs") => Some(Namespaced(Cow::from(rs))),
369+
("refs", "namespaces", _, "refs" | "HEAD") => Some(Namespaced(Cow::from(rs))),
369370

370371
_ => None,
371372
}

radicle-git-ext/t/src/git_ref_format/tests.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,17 @@ fn namespaced() {
156156
)
157157
}
158158

159+
#[test]
160+
fn namespaced_head() {
161+
assert_eq!(
162+
"refs/namespaces/foo/HEAD",
163+
refname!("refs/namespaces/foo/HEAD")
164+
.to_namespaced()
165+
.unwrap()
166+
.as_str()
167+
)
168+
}
169+
159170
#[test]
160171
fn not_namespaced() {
161172
assert!(name::REFS_HEADS_MAIN.to_namespaced().is_none())

0 commit comments

Comments
 (0)