Skip to content

Commit edb449c

Browse files
authored
Merge pull request #1825 from DianaNites/diananites-reftable
Add reftable test and archive
2 parents 5823b22 + 3c16e53 commit edb449c

File tree

14 files changed

+104
-20
lines changed

14 files changed

+104
-20
lines changed

gix-discover/src/is.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use std::{borrow::Cow, ffi::OsStr, path::Path};
2-
31
use crate::{DOT_GIT_DIR, MODULES};
2+
use std::{borrow::Cow, ffi::OsStr, path::Path};
43

54
/// Returns true if the given `git_dir` seems to be a bare repository.
65
///
@@ -67,21 +66,30 @@ pub(crate) fn git_with_metadata(
6766

6867
{
6968
// Fast-path: avoid doing the complete search if HEAD is already not there.
70-
// TODO(reftable): use a ref-store to lookup HEAD if ref-tables should be supported, or detect ref-tables beforehand.
71-
// Actually ref-tables still keep a specially marked `HEAD` around, so nothing might be needed here
72-
// Even though our head-check later would fail without supporting it.
7369
if !dot_git.join("HEAD").exists() {
7470
return Err(crate::is_git::Error::MissingHead);
7571
}
7672
// We expect to be able to parse any ref-hash, so we shouldn't have to know the repos hash here.
77-
// With ref-table, the has is probably stored as part of the ref-db itself, so we can handle it from there.
73+
// With ref-table, the hash is probably stored as part of the ref-db itself, so we can handle it from there.
7874
// In other words, it's important not to fail on detached heads here because we guessed the hash kind wrongly.
7975
let refs = gix_ref::file::Store::at(dot_git.as_ref().into(), Default::default());
80-
let head = refs.find_loose("HEAD")?;
81-
if head.name.as_bstr() != "HEAD" {
82-
return Err(crate::is_git::Error::MisplacedHead {
83-
name: head.name.into_inner(),
84-
});
76+
match refs.find_loose("HEAD") {
77+
Ok(head) => {
78+
if head.name.as_bstr() != "HEAD" {
79+
return Err(crate::is_git::Error::MisplacedHead {
80+
name: head.name.into_inner(),
81+
});
82+
}
83+
}
84+
Err(gix_ref::file::find::existing::Error::Find(gix_ref::file::find::Error::ReferenceCreation {
85+
source: _,
86+
relative_path,
87+
})) if relative_path == Path::new("HEAD") => {
88+
// It's fine as long as the reference is found is `HEAD`.
89+
}
90+
Err(err) => {
91+
return Err(err.into());
92+
}
8593
}
8694
}
8795

gix-discover/tests/discover/is_git/mod.rs renamed to gix-discover/tests/discover/is_git.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,18 @@ fn split_worktree_using_configuration() -> crate::Result {
130130
}
131131
Ok(())
132132
}
133+
134+
#[test]
135+
fn reftable() -> crate::Result {
136+
let repo_path = match gix_testtools::scripted_fixture_read_only("make_reftable_repo.sh") {
137+
Ok(root) => root.join("reftable-clone/.git"),
138+
Err(_) if *gix_testtools::GIT_VERSION < (2, 44, 0) => {
139+
eprintln!("Fixture script failure ignored as it looks like Git isn't recent enough.");
140+
return Ok(());
141+
}
142+
Err(err) => panic!("{err}"),
143+
};
144+
let kind = gix_discover::is_git(&repo_path)?;
145+
assert_eq!(kind, gix_discover::repository::Kind::WorkTree { linked_git_dir: None });
146+
Ok(())
147+
}
Binary file not shown.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
set -eu -o pipefail
3+
4+
git init -q
5+
6+
git checkout -b main
7+
touch this
8+
git add this
9+
git commit -q -m c1
10+
echo hello >> this
11+
git commit -q -am c2
12+
13+
git clone --ref-format=reftable . reftable-clone

gix-fs/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ pub struct Stack {
7777
}
7878

7979
#[cfg(unix)]
80-
/// Returns whether a a file has the executable permission set.
80+
/// Returns whether a file has the executable permission set.
8181
pub fn is_executable(metadata: &std::fs::Metadata) -> bool {
8282
use std::os::unix::fs::MetadataExt;
83-
(metadata.mode() & 0o100) != 0
83+
(metadata.mode() & 0o111) != 0
8484
}
8585

8686
/// Classifiers for IO-errors.

gix-validate/src/path.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ pub mod component {
2020
DotGitDir,
2121
#[error("The .gitmodules file must not be a symlink")]
2222
SymlinkedGitModules,
23+
#[error("Relative components '.' and '..' are disallowed")]
24+
Relative,
2325
}
2426

2527
/// Further specify what to check for in [`component()`](super::component())
@@ -78,6 +80,9 @@ pub fn component(
7880
if input.is_empty() {
7981
return Err(component::Error::Empty);
8082
}
83+
if input == ".." || input == "." {
84+
return Err(component::Error::Relative);
85+
}
8186
if protect_windows {
8287
if input.find_byteset(br"/\").is_some() {
8388
return Err(component::Error::PathSeparator);

gix-validate/tests/path/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ mod component {
253253
mktest!(con_with_extension, b"CON.abc", Error::WindowsReservedName);
254254
mktest!(con_with_middle, b"CON.tar.xz", Error::WindowsReservedName);
255255
mktest!(con_mixed_with_middle, b"coN.tar.xz ", Error::WindowsReservedName);
256+
mktest!(dot_dot, b"..", Error::Relative);
257+
mktest!(dot_dot_no_opts, b"..", Error::Relative, NO_OPTS);
258+
mktest!(single_dot, b".", Error::Relative);
259+
mktest!(single_dot_no_opts, b".", Error::Relative, NO_OPTS);
256260
mktest!(
257261
conout_mixed_with_extension,
258262
b"ConOut$ .xyz",
Binary file not shown.

0 commit comments

Comments
 (0)