summaryrefslogtreecommitdiffstats
path: root/vendor/gix-discover
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/gix-discover
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-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.json2
-rw-r--r--vendor/gix-discover/CHANGELOG.md160
-rw-r--r--vendor/gix-discover/Cargo.toml13
-rw-r--r--vendor/gix-discover/src/is.rs104
-rw-r--r--vendor/gix-discover/src/lib.rs2
-rw-r--r--vendor/gix-discover/src/upwards/mod.rs41
-rw-r--r--vendor/gix-discover/src/upwards/types.rs15
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,
}
}