diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/gix-discover | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-discover')
-rw-r--r-- | vendor/gix-discover/.cargo-checksum.json | 2 | ||||
-rw-r--r-- | vendor/gix-discover/CHANGELOG.md | 160 | ||||
-rw-r--r-- | vendor/gix-discover/Cargo.toml | 13 | ||||
-rw-r--r-- | vendor/gix-discover/src/is.rs | 104 | ||||
-rw-r--r-- | vendor/gix-discover/src/lib.rs | 2 | ||||
-rw-r--r-- | vendor/gix-discover/src/upwards/mod.rs | 41 | ||||
-rw-r--r-- | vendor/gix-discover/src/upwards/types.rs | 15 |
7 files changed, 264 insertions, 73 deletions
diff --git a/vendor/gix-discover/.cargo-checksum.json b/vendor/gix-discover/.cargo-checksum.json index a16a8eb97..b8dcb60f7 100644 --- a/vendor/gix-discover/.cargo-checksum.json +++ b/vendor/gix-discover/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"d6cc2d4c1a59d00c9c8d014f6ba3332bb7a6dcd98238e89b228ba24fcfd36054","Cargo.toml":"bc73856a6c97d777ecc5e0e299ec3280531e3f84a46dadfd213710eb2fdfeabf","src/is.rs":"570c5076a6de90a5eee8c035343adcfb138a14adc47879b38c17dd069d3ca301","src/lib.rs":"b410a24dc0545a780a8c808af601f9bd25a024b4ddc81b18ae4d6b44eb8753f9","src/parse.rs":"04a95307b39485f8ecd7b23c353ce4c0ba46dbe854f61fc037c7dff82f0d412b","src/path.rs":"965384fe931376235d7c2880c96ea9d92b6e3466073bc3e56d4ee83fe758934a","src/repository.rs":"d578255d18ed286cbf07bd965bae66f69c6f515926d6900b259482ecd9c1f812","src/upwards/mod.rs":"93976176f5f21a363ec79dfcff33fe9a1c6918621169e7fa602f10c7c1569205","src/upwards/types.rs":"6d2480b7388528a0031e07db12a4bdd2c696b562ab3b019c5093ac9d3beef5a5","src/upwards/util.rs":"ec03f84d0d84038c79c2f586aa6ceccfa6ae9e60e72cddb80cdf9c357011f160"},"package":"91c204adba5ebd211c74735cbb65817d277e154486bac0dffa3701f163b80350"}
\ No newline at end of file +{"files":{"CHANGELOG.md":"dc88835166aa9794ff3c6858a8a9a4ab653de752c7150265bbd47a5cc9ab9e3a","Cargo.toml":"9d81dfd6b9799486200291fecc877c1ef247f305ac70affc371bb20985ef28e0","src/is.rs":"78de018da25edab9e2ddac08cb3e4c9f256c4c373b1c0ba98de3ac4eb594c777","src/lib.rs":"7625dd1d6f3292c03948a3c69fe31b20aab98deb41a02d4a7fd727c6dbf30431","src/parse.rs":"04a95307b39485f8ecd7b23c353ce4c0ba46dbe854f61fc037c7dff82f0d412b","src/path.rs":"965384fe931376235d7c2880c96ea9d92b6e3466073bc3e56d4ee83fe758934a","src/repository.rs":"d578255d18ed286cbf07bd965bae66f69c6f515926d6900b259482ecd9c1f812","src/upwards/mod.rs":"53d946923255fd71c55fb3cbf5b0f6ff3b6f492ebc97acc2229f8bbbea75d91d","src/upwards/types.rs":"9068a525bc5c19034c1f0c14cfbbf2b8034ada10a4b857cfe69bc5e8d9de3541","src/upwards/util.rs":"ec03f84d0d84038c79c2f586aa6ceccfa6ae9e60e72cddb80cdf9c357011f160"},"package":"5012710ebdecf6193c6866d6409a3b702a4aa0d78c605bc343590b44ab9962a1"}
\ No newline at end of file diff --git a/vendor/gix-discover/CHANGELOG.md b/vendor/gix-discover/CHANGELOG.md index 3ad7302bf..0726ea080 100644 --- a/vendor/gix-discover/CHANGELOG.md +++ b/vendor/gix-discover/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.15.0 (2023-03-04) +## 0.18.0 (2023-04-27) A maintenance release without user-facing changes. @@ -14,6 +14,163 @@ A maintenance release without user-facing changes. <csr-read-only-do-not-edit/> - 2 commits contributed to the release. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Prepare changelogs prior to release ([`0135158`](https://github.com/Byron/gitoxide/commit/013515897215400539bfd53c25548bd054186ba6)) + - Bump gix-path v0.8.0, safety bump 20 crates (gix set to 0.44.1 manually) ([`43ebaf2`](https://github.com/Byron/gitoxide/commit/43ebaf267557218865862538ffc7bdf00558492f)) +</details> + +## 0.17.0 (2023-04-26) + +### New Features + + - <csr-id-1b8d9e6a408e480ae1912e919c37a26e5c46639d/> `discover_opts` supports an option to see non-bare repos only. + Knowing this allows for an optimization that saves a few syscalls + for maximum performance, or minimum penalty on very slow filesystems. + +### Bug Fixes + + - <csr-id-abbae1cbca6fb5c4347e51f7122f02d106c8d30a/> common-dir is now queried only when needed. + Previously it added costs that were accumulating during discovery. + - <csr-id-761324953a20d061f859c995180d603bb3734f9a/> speedup HEAD detection in `is_git()` + Previously it would always check with a `store` which has a fuzzy search + right now. Instead, we check once ourselves before trying to read HEAD + for validation. + - <csr-id-7543fab01c337c086c7b1331ad5fb1d48f9d11ac/> try `.git` subdir early for higher chances of success. + This will find worktrees faster, which should be most of the + dev directories out there. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 14 commits contributed to the release over the course of 23 calendar days. + - 27 days passed between releases. + - 4 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-hash v0.11.1, gix-path v0.7.4, gix-glob v0.6.0, gix-attributes v0.11.0, gix-config-value v0.11.0, gix-fs v0.1.1, gix-tempfile v5.0.3, gix-utils v0.1.1, gix-lock v5.0.1, gix-object v0.29.1, gix-ref v0.28.0, gix-sec v0.7.0, gix-config v0.21.0, gix-prompt v0.4.0, gix-url v0.17.0, gix-credentials v0.13.0, gix-diff v0.29.0, gix-discover v0.17.0, gix-hashtable v0.2.0, gix-ignore v0.1.0, gix-bitmap v0.2.3, gix-traverse v0.25.0, gix-index v0.16.0, gix-mailmap v0.12.0, gix-pack v0.34.0, gix-odb v0.44.0, gix-packetline v0.16.0, gix-transport v0.30.0, gix-protocol v0.31.0, gix-revision v0.13.0, gix-refspec v0.10.0, gix-worktree v0.16.0, gix v0.44.0, safety bump 7 crates ([`91134a1`](https://github.com/Byron/gitoxide/commit/91134a11c8ba0e942f692488ec9bce9fa1086324)) + - Prepare changelogs prior to release ([`30a1a71`](https://github.com/Byron/gitoxide/commit/30a1a71f36f24faac0e0b362ffdfedea7f9cdbf1)) + - Merge branch 'faster-discovery' ([`282a1a3`](https://github.com/Byron/gitoxide/commit/282a1a3f29572250e6d741c6daa97b0bed679753)) + - `discover_opts` supports an option to see non-bare repos only. ([`1b8d9e6`](https://github.com/Byron/gitoxide/commit/1b8d9e6a408e480ae1912e919c37a26e5c46639d)) + - Common-dir is now queried only when needed. ([`abbae1c`](https://github.com/Byron/gitoxide/commit/abbae1cbca6fb5c4347e51f7122f02d106c8d30a)) + - Avoid redundant metadata queries for directories ([`f36abd5`](https://github.com/Byron/gitoxide/commit/f36abd57ff0719edc2c95058832ef57ff8c53bba)) + - Speedup HEAD detection in `is_git()` ([`7613249`](https://github.com/Byron/gitoxide/commit/761324953a20d061f859c995180d603bb3734f9a)) + - Try `.git` subdir early for higher chances of success. ([`7543fab`](https://github.com/Byron/gitoxide/commit/7543fab01c337c086c7b1331ad5fb1d48f9d11ac)) + - Merge branch 'fix-823' ([`6ebd61e`](https://github.com/Byron/gitoxide/commit/6ebd61e548a36a04e413ac725a03e607a3588334)) + - Add test to assure we can handle bare repos with `index` file. ([`a68692b`](https://github.com/Byron/gitoxide/commit/a68692b5bfb8082f07dd907b091240106c6b358e)) + - Release gix-utils v0.1.0, gix-hash v0.11.0, gix-date v0.5.0, gix-features v0.29.0, gix-actor v0.20.0, gix-object v0.29.0, gix-archive v0.1.0, gix-fs v0.1.0, safety bump 25 crates ([`8dbd0a6`](https://github.com/Byron/gitoxide/commit/8dbd0a60557a85acfa231800a058cbac0271a8cf)) + - Release gix-hash v0.10.4, gix-hashtable v0.1.3 ([`b574a39`](https://github.com/Byron/gitoxide/commit/b574a3904203762a6b9e475e16a7c358d7616599)) + - Merge branch 'patch-1' ([`d0052c1`](https://github.com/Byron/gitoxide/commit/d0052c13cabcde8058177d2439053b50ea5adbfc)) + - Upgrade serial-test to v2 ([`6932017`](https://github.com/Byron/gitoxide/commit/69320174685e72940cd0fe600c94abb948a62bdd)) +</details> + +## 0.16.2 (2023-03-30) + +### Documentation + + - <csr-id-cc48c35d0ecf35824910c5b6ecc62fe9b2aff1b5/> fix minor typos + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 3 commits contributed to the release over the course of 2 calendar days. + - 4 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-path v0.7.3, gix-config-value v0.10.2, gix-config v0.20.1, gix-discover v0.16.2, gix-index v0.15.1, gix-odb v0.43.1, gix-packetline v0.15.1, gix-protocol v0.30.2, gix-worktree v0.15.2, gix v0.43.1 ([`38eed1d`](https://github.com/Byron/gitoxide/commit/38eed1d06e7cbb8fbcd54b2cad3163ca45e0baf1)) + - Fix minor typos ([`cc48c35`](https://github.com/Byron/gitoxide/commit/cc48c35d0ecf35824910c5b6ecc62fe9b2aff1b5)) + - Release gix-ref v0.27.2 ([`e965b18`](https://github.com/Byron/gitoxide/commit/e965b18aedcf13ec4538bc7bc700269a56ca615e)) +</details> + +## 0.16.1 (2023-03-26) + +A maintenance release without any user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 5 commits contributed to the release over the course of 15 calendar days. + - 15 days passed between releases. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-tempfile v5.0.2, gix-validate v0.7.4, gix-config v0.20.0, gix-prompt v0.3.3, gix-diff v0.28.1, gix-discover v0.16.1, gix-pack v0.33.2, gix-transport v0.29.1, gix-protocol v0.30.1, gix-revision v0.12.1, gix-worktree v0.15.1, gix v0.43.0, safety bump gix v0.43.0 ([`5dc1f9f`](https://github.com/Byron/gitoxide/commit/5dc1f9f2bcb8b3e147115fcb6f76558e8f48ffef)) + - Prepare changelogs prior to release ([`3016a28`](https://github.com/Byron/gitoxide/commit/3016a285f566bdfe7de2774fa6f2254c1b1a2c51)) + - Merge branch 'fix-790' ([`ee36e5b`](https://github.com/Byron/gitoxide/commit/ee36e5bb985e9ad90bc382cdd051a8b5295ca18c)) + - Less dependencies for tests (via `serial_test` no default features) ([`8f2accd`](https://github.com/Byron/gitoxide/commit/8f2accdf738def9aa4abdf08fc299d0e9807bc3e)) + - Merge branch 'fix-cred-helper' ([`01277a6`](https://github.com/Byron/gitoxide/commit/01277a681e4997896e04567490c572b5af606f35)) +</details> + +## 0.16.0 (2023-03-10) + +### Bug Fixes (BREAKING) + + - <csr-id-61ee9057f38d53d7cd4317503625359023747725/> add missing 'not' in error messages + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 4 commits contributed to the release. + - 6 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-tempfile v5.0.0, gix-lock v5.0.0, gix-ref v0.27.0, gix-config v0.19.0, gix-url v0.16.0, gix-credentials v0.12.0, gix-discover v0.16.0, gix-index v0.15.0, gix-pack v0.33.0, gix-odb v0.43.0, gix-transport v0.28.0, gix-protocol v0.29.0, gix-worktree v0.15.0, gix v0.41.0, safety bump 12 crates ([`29a0870`](https://github.com/Byron/gitoxide/commit/29a087043d1feb2f127b065341c8028d0bd0301e)) + - Prepare changelogs prior to release ([`e06f5f5`](https://github.com/Byron/gitoxide/commit/e06f5f523e83f4da390eddbebcb9a2d58674587b)) + - Merge branch '771_missing_negtive_in_error_message_returned_by_gix_discover' ([`7f6e67d`](https://github.com/Byron/gitoxide/commit/7f6e67d1339b9b9548d5ea012954c9e45588af9d)) + - Add missing 'not' in error messages ([`61ee905`](https://github.com/Byron/gitoxide/commit/61ee9057f38d53d7cd4317503625359023747725)) +</details> + +## 0.15.0 (2023-03-04) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 3 commits contributed to the release. - 3 days passed between releases. - 0 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -25,6 +182,7 @@ A maintenance release without user-facing changes. <details><summary>view details</summary> * **Uncategorized** + - Release gix-attributes v0.10.0, gix-ref v0.26.0, gix-config v0.18.0, gix-url v0.15.0, gix-credentials v0.11.0, gix-discover v0.15.0, gix-index v0.14.0, gix-mailmap v0.11.0, gix-odb v0.42.0, gix-transport v0.27.0, gix-protocol v0.28.0, gix-revision v0.12.0, gix-refspec v0.9.0, gix-worktree v0.14.0, gix v0.39.0 ([`93e75fe`](https://github.com/Byron/gitoxide/commit/93e75fed454ed8b342231bde4638db90e407ce52)) - Prepare changelogs prior to release ([`895e482`](https://github.com/Byron/gitoxide/commit/895e482badf01e953bb9144001eebd5e1b1c4d84)) - Release gix-features v0.28.0, gix-actor v0.19.0, gix-object v0.28.0, gix-diff v0.28.0, gix-traverse v0.24.0, gix-pack v0.32.0, safety bump 20 crates ([`0f411e9`](https://github.com/Byron/gitoxide/commit/0f411e93ec812592bb9d3a52b751399dd86f76f7)) </details> diff --git a/vendor/gix-discover/Cargo.toml b/vendor/gix-discover/Cargo.toml index ad10f7678..050a5e8f3 100644 --- a/vendor/gix-discover/Cargo.toml +++ b/vendor/gix-discover/Cargo.toml @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.64" name = "gix-discover" -version = "0.15.0" +version = "0.18.0" authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] include = [ "src/**/*", @@ -35,16 +35,16 @@ features = [ default-features = false [dependencies.gix-hash] -version = "^0.10.3" +version = "^0.11.1" [dependencies.gix-path] -version = "^0.7.2" +version = "^0.8.0" [dependencies.gix-ref] -version = "^0.26.0" +version = "^0.29.0" [dependencies.gix-sec] -version = "^0.6.2" +version = "^0.8.0" [dependencies.thiserror] version = "1.0.26" @@ -53,7 +53,8 @@ version = "1.0.26" version = "1.1.1" [dev-dependencies.serial_test] -version = "1.0.0" +version = "2.0.0" +default-features = false [target."cfg(any(unix, windows))".dev-dependencies.tempfile] version = "3.2.0" diff --git a/vendor/gix-discover/src/is.rs b/vendor/gix-discover/src/is.rs index e5feb16da..e5d554452 100644 --- a/vendor/gix-discover/src/is.rs +++ b/vendor/gix-discover/src/is.rs @@ -10,7 +10,7 @@ pub fn bare(git_dir_candidate: impl AsRef<Path>) -> bool { !(git_dir.join("index").exists() || (git_dir.file_name() == Some(OsStr::new(DOT_GIT_DIR)))) } -/// Returns true if `git_dir` is is located within a `.git/modules` directory, indicating it's a submodule clone. +/// Returns true if `git_dir` is located within a `.git/modules` directory, indicating it's a submodule clone. pub fn submodule_git_dir(git_dir: impl AsRef<Path>) -> bool { let git_dir = git_dir.as_ref(); @@ -39,6 +39,18 @@ pub fn submodule_git_dir(git_dir: impl AsRef<Path>) -> bool { /// * …a refs directory /// pub fn git(git_dir: impl AsRef<Path>) -> Result<crate::repository::Kind, crate::is_git::Error> { + let git_dir = git_dir.as_ref(); + let git_dir_metadata = git_dir.metadata().map_err(|err| crate::is_git::Error::Metadata { + source: err, + path: git_dir.into(), + })?; + git_with_metadata(git_dir, git_dir_metadata) +} + +pub(crate) fn git_with_metadata( + git_dir: &Path, + git_dir_metadata: std::fs::Metadata, +) -> Result<crate::repository::Kind, crate::is_git::Error> { #[derive(Eq, PartialEq)] enum Kind { MaybeRepo, @@ -46,17 +58,39 @@ pub fn git(git_dir: impl AsRef<Path>) -> Result<crate::repository::Kind, crate:: LinkedWorkTreeDir, WorkTreeGitDir { work_dir: std::path::PathBuf }, } - let git_dir = git_dir.as_ref(); - let (dot_git, common_dir, kind) = if git_dir - .metadata() - .map_err(|err| crate::is_git::Error::Metadata { - source: err, - path: git_dir.into(), - })? - .is_file() - { + + let dot_git = 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"); + Cow::Owned(private_git_dir) + } else { + Cow::Borrowed(git_dir) + }; + + { + // Fast-path: avoid doing the complete search if HEAD is already not there. + // TODO(reftable): use a ref-store to lookup HEAD if ref-tables should be supported, or detect ref-tables beforehand. + if !dot_git.join("HEAD").exists() { + return Err(crate::is_git::Error::MissingHead); + } + // We expect to be able to parse any ref-hash, so we shouldn't have to know the repos hash here. + // With ref-table, the has is probably stored as part of the ref-db itself, so we can handle it from there. + // In other words, it's important not to fail on detached heads here because we guessed the hash kind wrongly. + let object_hash_should_not_matter_here = gix_hash::Kind::Sha1; + let refs = gix_ref::file::Store::at( + dot_git.as_ref(), + gix_ref::store::WriteReflog::Normal, + object_hash_should_not_matter_here, + ); + let head = refs.find_loose("HEAD")?; + if head.name.as_bstr() != "HEAD" { + return Err(crate::is_git::Error::MisplacedHead { + name: head.name.into_inner(), + }); + } + } + + let (common_dir, kind) = if git_dir_metadata.is_file() { + let common_dir = dot_git.join("commondir"); match crate::path::from_plain_file(&common_dir) { Some(Err(err)) => { return Err(crate::is_git::Error::MissingCommonDir { @@ -65,60 +99,30 @@ pub fn git(git_dir: impl AsRef<Path>) -> Result<crate::repository::Kind, crate:: }) } Some(Ok(common_dir)) => { - let common_dir = private_git_dir.join(common_dir); - ( - Cow::Owned(private_git_dir), - Cow::Owned(common_dir), - Kind::LinkedWorkTreeDir, - ) + let common_dir = dot_git.join(common_dir); + (Cow::Owned(common_dir), Kind::LinkedWorkTreeDir) } - None => ( - Cow::Owned(private_git_dir.clone()), - Cow::Owned(private_git_dir), - Kind::Submodule, - ), + None => (dot_git.clone(), Kind::Submodule), } } else { - let common_dir = git_dir.join("commondir"); + let common_dir = dot_git.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")) + crate::path::from_plain_file(dot_git.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 }, - ) + let common_dir = dot_git.join(common_dir); + (Cow::Owned(common_dir), Kind::WorkTreeGitDir { work_dir }) } - None => (Cow::Borrowed(git_dir), Cow::Borrowed(git_dir), Kind::MaybeRepo), + None => (dot_git.clone(), Kind::MaybeRepo), } }; { - // We expect to be able to parse any ref-hash, so we shouldn't have to know the repos hash here. - // With ref-table, the has is probably stored as part of the ref-db itself, so we can handle it from there. - // In other words, it's important not to fail on detached heads here because we guessed the hash kind wrongly. - let object_hash_should_not_matter_here = gix_hash::Kind::Sha1; - let refs = gix_ref::file::Store::at( - dot_git.as_ref(), - gix_ref::store::WriteReflog::Normal, - object_hash_should_not_matter_here, - ); - let head = refs.find_loose("HEAD")?; - if head.name.as_bstr() != "HEAD" { - return Err(crate::is_git::Error::MisplacedHead { - name: head.name.into_inner(), - }); - } - } - - { let objects_path = common_dir.join("objects"); if !objects_path.is_dir() { return Err(crate::is_git::Error::MissingObjectsDirectory { missing: objects_path }); @@ -139,7 +143,7 @@ pub fn git(git_dir: impl AsRef<Path>) -> Result<crate::repository::Kind, crate:: git_dir: dot_git.into_owned(), }, Kind::MaybeRepo => { - if bare(git_dir) { + if bare(git_dir) || git_dir.extension() == Some(OsStr::new("git")) { crate::repository::Kind::Bare } else if submodule_git_dir(git_dir) { crate::repository::Kind::SubmoduleGitDir diff --git a/vendor/gix-discover/src/lib.rs b/vendor/gix-discover/src/lib.rs index b522ae1c2..5a350b239 100644 --- a/vendor/gix-discover/src/lib.rs +++ b/vendor/gix-discover/src/lib.rs @@ -23,6 +23,8 @@ pub mod is_git { pub enum Error { #[error("Could not find a valid HEAD reference")] FindHeadRef(#[from] gix_ref::file::find::existing::Error), + #[error("Missing HEAD at '.git/HEAD'")] + MissingHead, #[error("Expected HEAD at '.git/HEAD', got '.git/{}'", .name)] MisplacedHead { name: bstr::BString }, #[error("Expected an objects directory at '{}'", .missing.display())] diff --git a/vendor/gix-discover/src/upwards/mod.rs b/vendor/gix-discover/src/upwards/mod.rs index 8b041f443..87e6a18b4 100644 --- a/vendor/gix-discover/src/upwards/mod.rs +++ b/vendor/gix-discover/src/upwards/mod.rs @@ -4,6 +4,7 @@ pub use types::{Error, Options}; mod util; pub(crate) mod function { + use std::ffi::OsStr; use std::{borrow::Cow, path::Path}; use gix_sec::Trust; @@ -12,6 +13,7 @@ pub(crate) mod function { #[cfg(unix)] use crate::upwards::util::device_id; use crate::{ + is::git_with_metadata as is_git_with_metadata, is_git, upwards::util::{find_ceiling_height, shorten_path_with_cwd}, DOT_GIT_DIR, @@ -31,6 +33,7 @@ pub(crate) mod function { match_ceiling_dir_or_error, cross_fs, current_dir, + dot_git_only, }: Options<'_>, ) -> Result<(crate::repository::Path, Trust), Error> { // Normalize the path so that `Path::parent()` _actually_ gives @@ -80,6 +83,7 @@ pub(crate) mod function { let mut cursor = dir.clone().into_owned(); let mut current_height = 0; + let mut cursor_metadata = Some(dir_metadata); 'outer: loop { if max_height.map_or(false, |x| current_height > x) { return Err(Error::NoGitRepositoryWithinCeiling { @@ -91,13 +95,15 @@ pub(crate) mod function { #[cfg(unix)] if current_height != 0 && !cross_fs { - let metadata = if cursor.as_os_str().is_empty() { - Path::new(".") - } else { - cursor.as_ref() - } - .metadata() - .map_err(|_| Error::InaccessibleDirectory { path: cursor.clone() })?; + let metadata = cursor_metadata.take().map(Ok).unwrap_or_else(|| { + if cursor.as_os_str().is_empty() { + Path::new(".") + } else { + cursor.as_ref() + } + .metadata() + .map_err(|_| Error::InaccessibleDirectory { path: cursor.clone() }) + })?; if device_id(&metadata) != initial_device { return Err(Error::NoGitRepositoryWithinFs { @@ -105,13 +111,21 @@ pub(crate) mod function { limit: cursor.clone(), }); } + cursor_metadata = Some(metadata); } - for append_dot_git in &[false, true] { - if *append_dot_git { + let mut cursor_metadata_backup = None; + let started_as_dot_git = cursor.file_name() == Some(OsStr::new(DOT_GIT_DIR)); + let dir_manipulation = if dot_git_only { &[true] as &[_] } else { &[true, false] }; + for append_dot_git in dir_manipulation { + if *append_dot_git && !started_as_dot_git { cursor.push(DOT_GIT_DIR); + cursor_metadata_backup = cursor_metadata.take(); } - if let Ok(kind) = is_git(&cursor) { + if let Ok(kind) = match cursor_metadata.take() { + Some(metadata) => is_git_with_metadata(&cursor, metadata), + None => is_git(&cursor), + } { match filter_by_trust(&cursor)? { Some(trust) => { // TODO: test this more, it definitely doesn't always find the shortest path to a directory @@ -138,8 +152,13 @@ pub(crate) mod function { } } } - if *append_dot_git { + + // Usually `.git` (started_as_dot_git == true) will be a git dir, but if not we can quickly skip over it. + if *append_dot_git || started_as_dot_git { cursor.pop(); + if let Some(metadata) = cursor_metadata_backup.take() { + cursor_metadata = Some(metadata); + } } } if cursor.parent().map_or(false, |p| p.as_os_str().is_empty()) { diff --git a/vendor/gix-discover/src/upwards/types.rs b/vendor/gix-discover/src/upwards/types.rs index 52ce9db9c..d8fb19d49 100644 --- a/vendor/gix-discover/src/upwards/types.rs +++ b/vendor/gix-discover/src/upwards/types.rs @@ -10,15 +10,15 @@ pub enum Error { InvalidInput { directory: PathBuf }, #[error("Failed to access a directory, or path is not a directory: '{}'", .path.display())] InaccessibleDirectory { path: PathBuf }, - #[error("Could find a git repository in '{}' or in any of its parents", .path.display())] + #[error("Could not find a git repository in '{}' or in any of its parents", .path.display())] NoGitRepository { path: PathBuf }, - #[error("Could find a git repository in '{}' or in any of its parents within ceiling height of {}", .path.display(), .ceiling_height)] + #[error("Could not find a git repository in '{}' or in any of its parents within ceiling height of {}", .path.display(), .ceiling_height)] NoGitRepositoryWithinCeiling { path: PathBuf, ceiling_height: usize }, - #[error("Could find a git repository in '{}' or in any of its parents within device limits below '{}'", .path.display(), .limit.display())] + #[error("Could not find a git repository in '{}' or in any of its parents within device limits below '{}'", .path.display(), .limit.display())] NoGitRepositoryWithinFs { path: PathBuf, limit: PathBuf }, #[error("None of the passed ceiling directories prefixed the git-dir candidate, making them ineffective.")] NoMatchingCeilingDir, - #[error("Could find a trusted git repository in '{}' or in any of its parents, candidate at '{}' discarded", .path.display(), .candidate.display())] + #[error("Could not find a trusted git repository in '{}' or in any of its parents, candidate at '{}' discarded", .path.display(), .candidate.display())] NoTrustedGitRepository { path: PathBuf, candidate: PathBuf, @@ -53,6 +53,12 @@ pub struct Options<'a> { // TODO: test on Linux // TODO: Handle WASI once https://github.com/rust-lang/rust/issues/71213 is resolved pub cross_fs: bool, + /// If true, limit discovery to `.git` directories. + /// + /// This will fail to find typical bare repositories, but would find them if they happen to be named `.git`. + /// Use this option if repos with worktrees are the only kind of repositories you are interested in for + /// optimal discovery performance. + pub dot_git_only: bool, /// If set, the _current working directory_ (absolute path) to use when resolving relative paths. Note that /// that this is merely an optimization for those who discover a lot of repositories in the same process. /// @@ -67,6 +73,7 @@ impl Default for Options<'_> { ceiling_dirs: vec![], match_ceiling_dir_or_error: true, cross_fs: false, + dot_git_only: false, current_dir: None, } } |