Skip to content

Commit

Permalink
determine filesystem case (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Feb 28, 2022
1 parent 43272f3 commit cb8fa0b
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 6 deletions.
23 changes: 19 additions & 4 deletions git-worktree/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,37 @@ pub struct Context {
}

impl Context {
/// try to determine all values in this context by probing them in the given `directory`, which
/// try to determine all values in this context by probing them in the given `git_dir`, which
/// should be on the file system the git repository is located on.
/// `git_dir` is a typical git repository, expected to be populated with the typical files like `config`.
///
/// All errors are ignored and interpreted on top of the default for the platform the binary is compiled for.
pub fn probe(directory: impl AsRef<std::path::Path>) -> Self {
let root = directory.as_ref();
pub fn probe(git_dir: impl AsRef<std::path::Path>) -> Self {
let root = git_dir.as_ref();
let ctx = Context::default();
Context {
symlink: Self::probe_symlink(root).unwrap_or(ctx.symlink),
ignore_case: Self::probe_ignore_case(root).unwrap_or(ctx.ignore_case),
..ctx
}
}

fn probe_ignore_case(git_dir: &Path) -> std::io::Result<bool> {
std::fs::metadata(git_dir.join("cOnFiG")).map(|_| true).or_else(|err| {
if err.kind() == std::io::ErrorKind::NotFound {
Ok(false)
} else {
Err(err)
}
})
}

fn probe_symlink(root: &Path) -> std::io::Result<bool> {
let src_path = root.join("__link_src_file");
std::fs::File::options().create_new(true).write(true).open(&src_path)?;
std::fs::OpenOptions::new()
.create_new(true)
.write(true)
.open(&src_path)?;
let link_path = root.join("__file_link");
if symlink::symlink_file(&src_path, &link_path).is_err() {
std::fs::remove_file(&src_path)?;
Expand Down
5 changes: 4 additions & 1 deletion git-worktree/tests/fs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#[test]
fn from_probing_cwd() {
let dir = tempfile::tempdir().unwrap();
let _ctx = git_worktree::fs::Context::probe(dir.path());
std::fs::File::create(dir.path().join("config")).unwrap();
let ctx = git_worktree::fs::Context::probe(dir.path());
dbg!(ctx);
let entries: Vec<_> = std::fs::read_dir(dir.path())
.unwrap()
.filter_map(Result::ok)
.filter(|e| e.file_name().to_str() != Some("config"))
.map(|e| e.path().to_owned())
.collect();
assert_eq!(
Expand Down
2 changes: 1 addition & 1 deletion git-worktree/tests/index/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mod checkout {
#[test]
fn allow_symlinks() -> crate::Result {
let opts = opts_with_symlink(true);
if !git_worktree::fs::Context::probe(std::env::current_dir()?).symlink {
if !git_worktree::fs::Context::probe(std::env::current_dir()?.join("..").join(".git")).symlink {
eprintln!("IGNORING symlink test on file system without symlink support");
// skip if symlinks aren't supported anyway.
return Ok(());
Expand Down

0 comments on commit cb8fa0b

Please sign in to comment.