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.
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/tests/gix/repository/open.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,33 @@ fn on_root_with_decomposed_unicode() -> crate::Result {
5555
Ok(())
5656
}
5757

58+
#[test]
59+
fn non_bare_reftable() -> crate::Result {
60+
let repo = match named_subrepo_opts(
61+
"make_reftable_repo.sh",
62+
"reftable-clone",
63+
gix::open::Options::isolated(),
64+
) {
65+
Ok(r) => r,
66+
Err(_) if *gix_testtools::GIT_VERSION < (2, 44, 0) => {
67+
eprintln!("Fixture script failure ignored as it looks like Git isn't recent enough.");
68+
return Ok(());
69+
}
70+
Err(err) => panic!("{err}"),
71+
};
72+
assert!(
73+
repo.head_id().is_err(),
74+
"Trying to do anything with head will fail as we don't support reftables yet"
75+
);
76+
assert!(!repo.is_bare());
77+
assert_ne!(
78+
repo.workdir(),
79+
None,
80+
"Otherwise it can be used, but it's hard to do without refs"
81+
);
82+
Ok(())
83+
}
84+
5885
#[test]
5986
fn bare_repo_with_index() -> crate::Result {
6087
let repo = named_subrepo_opts(

gix/tests/gix/util.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ pub fn named_subrepo_opts(
3838
name: &str,
3939
opts: open::Options,
4040
) -> std::result::Result<Repository, gix::open::Error> {
41-
let repo_path = gix_testtools::scripted_fixture_read_only(fixture).unwrap().join(name);
41+
let repo_path = gix_testtools::scripted_fixture_read_only(fixture)
42+
.map_err(|err| gix::open::Error::Io(std::io::Error::other(err)))?
43+
.join(name);
4244
Ok(ThreadSafeRepository::open_opts(repo_path, opts)?.to_thread_local())
4345
}
4446

tests/tools/src/lib.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -583,13 +583,10 @@ fn scripted_fixture_read_only_with_args_inner(
583583
};
584584
if !output.status.success() {
585585
write_failure_marker(&failure_marker);
586+
eprintln!("stdout: {}", output.stdout.as_bstr());
587+
eprintln!("stderr: {}", output.stderr.as_bstr());
588+
return Err(format!("fixture script of {cmd:?} failed").into());
586589
}
587-
assert!(
588-
output.status.success(),
589-
"fixture script of {cmd:?} failed: stdout: {}\nstderr: {}",
590-
output.stdout.as_bstr(),
591-
output.stderr.as_bstr()
592-
);
593590
create_archive_if_we_should(
594591
&script_result_directory,
595592
&archive_file_path,

0 commit comments

Comments
 (0)