🏡 index : ~doyle/rgit.git

author Jordan Doyle <jordan@doyle.la> 2025-01-07 16:10:43.0 +07:00:00
committer Jordan Doyle <jordan@doyle.la> 2025-01-07 16:10:43.0 +07:00:00
commit
dd440d9b8c4e50832996645afb78d8d3a63acbda [patch]
tree
dc9aa1fcdde913fe637d52d1d513acdd392643eb
parent
7c5c909cde404d6a886b522d93524d8a06bcfa8c
download
dd440d9b8c4e50832996645afb78d8d3a63acbda.tar.gz

Use gix to determine whether something is a git repository rather than a heuristic

Fixes #95

Diff

 src/database/indexer.rs | 37 +++++++++++++++----------------------
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/src/database/indexer.rs b/src/database/indexer.rs
index c6a80a9..6b75cc3 100644
--- a/src/database/indexer.rs
+++ a/src/database/indexer.rs
@@ -44,8 +44,8 @@
    let mut discovered = Vec::new();
    discover_repositories(scan_path, &mut discovered);

    for repository in discovered {
        let Some(relative) = get_relative_path(scan_path, &repository) else {
    for (repository_path, git_repository) in discovered {
        let Some(relative) = get_relative_path(scan_path, &repository_path) else {
            continue;
        };

@@ -65,23 +65,11 @@
        let Some(name) = relative.file_name().and_then(OsStr::to_str) else {
            continue;
        };
        let description = std::fs::read(repository.join("description")).unwrap_or_default();
        let description = std::fs::read(repository_path.join("description")).unwrap_or_default();
        let description = String::from_utf8(description)
            .ok()
            .filter(|v| !v.is_empty());

        let repository_path = scan_path.join(relative);

        let mut git_repository = match gix::open(repository_path.clone()) {
            Ok(v) => v,
            Err(error) => {
                warn!(%error, "Failed to open repository {} to update metadata, skipping", relative.display());
                continue;
            }
        };

        git_repository.object_cache_size(10 * 1024 * 1024);

        let res = Repository {
            id,
            name: name.to_string(),
@@ -414,7 +402,7 @@
    full_path.strip_prefix(relative_to).ok()
}

fn discover_repositories(current: &Path, discovered_repos: &mut Vec<PathBuf>) {
fn discover_repositories(current: &Path, discovered_repos: &mut Vec<(PathBuf, gix::Repository)>) {
    let current = match std::fs::read_dir(current) {
        Ok(v) => v,
        Err(error) => {
@@ -429,12 +417,17 @@
        .filter(|path| path.is_dir());

    for dir in dirs {
        if dir.join("packed-refs").is_file() {
            // we've hit what looks like a bare git repo, lets take it
            discovered_repos.push(dir);
        } else {
            // probably not a bare git repo, lets recurse deeper
            discover_repositories(&dir, discovered_repos);
        match gix::open_opts(&dir, gix::open::Options::default().open_path_as_is(true)) {
            Ok(mut repo) => {
                repo.object_cache_size(10 * 1024 * 1024);
                discovered_repos.push((dir, repo));
            }
            Err(gix::open::Error::NotARepository { .. }) => {
                discover_repositories(&dir, discovered_repos);
            }
            Err(error) => {
                warn!(%error, "Failed to open repository {} for indexing", dir.display());
            }
        }
    }
}