Skip to content

Commit

Permalink
Merge branch 'macos-exfat'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Sep 1, 2022
2 parents ce01093 + 2cd1c00 commit f256f8f
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 57 deletions.
89 changes: 38 additions & 51 deletions git-discover/src/is.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,64 +46,51 @@ pub fn git(git_dir: impl AsRef<Path>) -> Result<crate::repository::Kind, crate::
LinkedWorkTreeDir,
WorkTreeGitDir { work_dir: std::path::PathBuf },
}
#[cfg(not(windows))]
fn is_directory(err: &std::io::Error) -> bool {
err.raw_os_error() == Some(21)
}
// TODO: use ::IsDirectory as well when stabilized, but it's permission denied on windows
#[cfg(windows)]
fn is_directory(err: &std::io::Error) -> bool {
err.kind() == std::io::ErrorKind::PermissionDenied
}
let git_dir = git_dir.as_ref();
let (dot_git, common_dir, kind) = match crate::path::from_gitdir_file(git_dir) {
Ok(private_git_dir) => {
let common_dir = private_git_dir.join("commondir");
match crate::path::from_plain_file(&common_dir) {
Some(Err(err)) => {
return Err(crate::is_git::Error::MissingCommonDir {
missing: common_dir,
source: err,
})
}
Some(Ok(common_dir)) => {
let common_dir = private_git_dir.join(common_dir);
(
Cow::Owned(private_git_dir),
Cow::Owned(common_dir),
Kind::LinkedWorkTreeDir,
)
}
None => (
Cow::Owned(private_git_dir.clone()),
let (dot_git, common_dir, kind) = if git_dir.metadata()?.is_file() {
let private_git_dir = crate::path::from_gitdir_file(git_dir)?;
let common_dir = private_git_dir.join("commondir");
match crate::path::from_plain_file(&common_dir) {
Some(Err(err)) => {
return Err(crate::is_git::Error::MissingCommonDir {
missing: common_dir,
source: err,
})
}
Some(Ok(common_dir)) => {
let common_dir = private_git_dir.join(common_dir);
(
Cow::Owned(private_git_dir),
Kind::Submodule,
),
Cow::Owned(common_dir),
Kind::LinkedWorkTreeDir,
)
}
None => (
Cow::Owned(private_git_dir.clone()),
Cow::Owned(private_git_dir),
Kind::Submodule,
),
}
Err(crate::path::from_gitdir_file::Error::Io(err)) if is_directory(&err) => {
let common_dir = git_dir.join("commondir");
let worktree_and_common_dir =
crate::path::from_plain_file(common_dir)
} else {
let common_dir = git_dir.join("commondir");
let worktree_and_common_dir = crate::path::from_plain_file(common_dir)
.and_then(Result::ok)
.and_then(|cd| {
crate::path::from_plain_file(git_dir.join("gitdir"))
.and_then(Result::ok)
.and_then(|cd| {
crate::path::from_plain_file(git_dir.join("gitdir"))
.and_then(Result::ok)
.map(|worktree_gitfile| (crate::path::without_dot_git_dir(worktree_gitfile), cd))
});
match worktree_and_common_dir {
Some((work_dir, common_dir)) => {
let common_dir = git_dir.join(common_dir);
(
Cow::Borrowed(git_dir),
Cow::Owned(common_dir),
Kind::WorkTreeGitDir { work_dir },
)
}
None => (Cow::Borrowed(git_dir), Cow::Borrowed(git_dir), Kind::MaybeRepo),
.map(|worktree_gitfile| (crate::path::without_dot_git_dir(worktree_gitfile), cd))
});
match worktree_and_common_dir {
Some((work_dir, common_dir)) => {
let common_dir = git_dir.join(common_dir);
(
Cow::Borrowed(git_dir),
Cow::Owned(common_dir),
Kind::WorkTreeGitDir { work_dir },
)
}
None => (Cow::Borrowed(git_dir), Cow::Borrowed(git_dir), Kind::MaybeRepo),
}
Err(err) => return Err(err.into()),
};

{
Expand Down
2 changes: 2 additions & 0 deletions git-discover/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub mod is_git {
MissingRefsDirectory { missing: PathBuf },
#[error(transparent)]
GitFile(#[from] crate::path::from_gitdir_file::Error),
#[error("Could not retrieve metadata")]
Metadata(#[from] std::io::Error),
}
}

Expand Down
1 change: 1 addition & 0 deletions git-discover/tests/discover.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub use git_testtools::Result;

mod is_git;
mod parse;
mod path;
mod upwards;
Git LFS file not shown
22 changes: 22 additions & 0 deletions git-discover/tests/fixtures/make_exfat_repo_darwin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
set -eu -o pipefail

[[ $(uname) == Darwin ]] || exit 1

dmg_file=exfat_repo.dmg
hdiutil create -size 10m -fs exfat -volname "test" $dmg_file

mount=exfat_mount
mkdir $mount
hdiutil attach $dmg_file -nobrowse -mountpoint $mount

(cd $mount
git init -q
git checkout -b main
touch this
git add this
git commit -q -m c1
)

hdiutil detach $mount
rm -R $mount
38 changes: 38 additions & 0 deletions git-discover/tests/is_git/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#[cfg(target_os = "macos")]
#[test]
fn verify_on_exfat() -> crate::Result<()> {
use git_discover::repository::Kind;
use std::process::Command;

let fixtures = git_testtools::scripted_fixture_repo_read_only("make_exfat_repo_darwin.sh")?;
let mount_point = tempfile::tempdir()?;

let _cleanup = {
// Mount dmg file
Command::new("hdiutil")
.args(&["attach", "-nobrowse", "-mountpoint"])
.arg(mount_point.path())
.arg(fixtures.as_path().join("exfat_repo.dmg"))
.status()?;

// Ensure that the mount point is always cleaned up
defer::defer({
let mount_point = mount_point.path().to_owned();
move || {
Command::new("hdiutil")
.arg("detach")
.arg(&mount_point)
.status()
.expect("detach temporary test dmg filesystem successfully");
}
})
};

let is_git = git_discover::is_git(mount_point.path().join(".git"));

assert!(
matches!(is_git, Ok(Kind::WorkTree { linked_git_dir: None })),
"repo on exFAT is recognized as a valid worktree repo"
);
Ok(())
}
11 changes: 5 additions & 6 deletions git-discover/tests/upwards/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,11 @@ fn cross_fs() -> crate::Result {
.arg(&dmg_file)
.status()?;

// Symlink the mount point into the repo
symlink(mount_point.path(), top_level_repo.path().join("remote"))?;

// Ensure that the mount point is always cleaned up
let cleanup = defer::defer({
defer::defer({
let arg = mount_point.path().to_owned();
move || {
Command::new("hdiutil")
Expand All @@ -212,11 +215,7 @@ fn cross_fs() -> crate::Result {
.status()
.expect("detach temporary test dmg filesystem successfully");
}
});

// Symlink the mount point into the repo
symlink(mount_point.path(), top_level_repo.path().join("remote"))?;
cleanup
})
};

let res = git_discover::upwards(top_level_repo.path().join("remote"))
Expand Down

0 comments on commit f256f8f

Please sign in to comment.