Skip to content

Commit 29898e3

Browse files
committedAug 7, 2024··
Merge branch 'improvements'
2 parents 2e00b5e + 6ac2867 commit 29898e3

File tree

8 files changed

+86
-8
lines changed

8 files changed

+86
-8
lines changed
 

Diff for: ‎gix/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ max-control = ["parallel", "pack-cache-lru-static", "pack-cache-lru-dynamic"]
208208
## on some platforms.
209209
## Note that this configuration still uses a pure Rust zlib implementation which isn't the fastest compared to its C-alternatives.
210210
## No C toolchain is involved.
211-
max-performance-safe = ["max-control", "parallel-walkdir"]
211+
max-performance-safe = ["max-control"]
212212

213213
## If set, walkdir iterators will be multi-threaded which affects the listing of loose objects and references.
214214
## Note, however, that this will use `rayon` under the hood and spawn threads for each traversal to avoid a global rayon thread pool.

Diff for: ‎gix/src/reference/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ impl<'repo> Reference<'repo> {
7474
Ok(Id::from_id(oid, self.repo))
7575
}
7676

77+
/// Follow all symbolic targets this reference might point to and peel the underlying object
78+
/// to the end of the chain, and return it, reusing the `packed` buffer if available.
79+
///
80+
/// This is useful to learn where this reference is ultimately pointing to.
81+
pub fn peel_to_id_in_place_packed(
82+
&mut self,
83+
packed: Option<&gix_ref::packed::Buffer>,
84+
) -> Result<Id<'repo>, peel::Error> {
85+
let oid = self
86+
.inner
87+
.peel_to_id_in_place_packed(&self.repo.refs, &self.repo.objects, packed)?;
88+
Ok(Id::from_id(oid, self.repo))
89+
}
90+
7791
/// Similar to [`peel_to_id_in_place()`][Reference::peel_to_id_in_place()], but consumes this instance.
7892
pub fn into_fully_peeled_id(mut self) -> Result<Id<'repo>, peel::Error> {
7993
self.peel_to_id_in_place()

Diff for: ‎gix/src/reference/remote.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use crate::bstr::ByteSlice;
12
use crate::repository::{branch_remote_ref_name, branch_remote_tracking_ref_name};
23
use crate::{remote, Reference};
3-
use gix_ref::FullNameRef;
4+
use gix_ref::{Category, FullNameRef};
45
use std::borrow::Cow;
56

67
/// Remotes
@@ -9,8 +10,31 @@ impl<'repo> Reference<'repo> {
910
/// Return `None` if no remote is configured.
1011
///
1112
/// See also [`Repository::branch_remote_name()`](crate::Repository::branch_remote_name()) for more details.
12-
pub fn remote_name(&self, direction: remote::Direction) -> Option<remote::Name<'repo>> {
13-
self.repo.branch_remote_name(self.name().shorten(), direction)
13+
pub fn remote_name(&self, direction: remote::Direction) -> Option<remote::Name<'_>> {
14+
let (category, shortname) = self.name().category_and_short_name()?;
15+
match category {
16+
Category::RemoteBranch => {
17+
if shortname.find_iter("/").take(2).count() == 1 {
18+
let slash_pos = shortname.find_byte(b'/').expect("it was just found");
19+
shortname[..slash_pos]
20+
.as_bstr()
21+
.to_str()
22+
.ok()
23+
.map(|n| remote::Name::Symbol(n.into()))
24+
} else {
25+
let remotes = self.repo.remote_names();
26+
for slash_pos in shortname.rfind_iter("/") {
27+
let candidate = shortname[..slash_pos].as_bstr();
28+
if remotes.contains(candidate) {
29+
return candidate.to_str().ok().map(|n| remote::Name::Symbol(n.into()));
30+
}
31+
}
32+
None
33+
}
34+
}
35+
Category::LocalBranch => self.repo.branch_remote_name(shortname, direction),
36+
_ => None,
37+
}
1438
}
1539

1640
/// Find the remote along with all configuration associated with it suitable for handling this reference.

Diff for: ‎gix/src/remote/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::borrow::Cow;
2-
31
use crate::bstr::BStr;
2+
use std::borrow::Cow;
3+
use std::collections::BTreeSet;
44

55
/// The direction of an operation carried out (or to be carried out) through a remote.
66
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
@@ -31,6 +31,9 @@ pub enum Name<'repo> {
3131
Url(Cow<'repo, BStr>),
3232
}
3333

34+
/// A type-definition for a sorted list of unvalidated remote names - they have been read straight from the configuration.
35+
pub type Names<'a> = BTreeSet<Cow<'a, BStr>>;
36+
3437
///
3538
#[allow(clippy::empty_docs)]
3639
pub mod name;

Diff for: ‎gix/src/repository/config/remote.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::bstr::BStr;
2-
use std::{borrow::Cow, collections::BTreeSet};
2+
use std::borrow::Cow;
33

44
use crate::config::tree::{Remote, Section};
55
use crate::remote;
@@ -8,7 +8,7 @@ use crate::remote;
88
impl crate::Repository {
99
/// Returns a sorted list unique of symbolic names of remotes that
1010
/// we deem [trustworthy][crate::open::Options::filter_config_section()].
11-
pub fn remote_names(&self) -> BTreeSet<Cow<'_, BStr>> {
11+
pub fn remote_names(&self) -> remote::Names<'_> {
1212
self.config
1313
.resolved
1414
.sections_by_name(Remote.name())
Binary file not shown.

Diff for: ‎gix/tests/fixtures/make_remote_config_repos.sh

+10
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,13 @@ EOF
131131
pushDefault = push-origin
132132
EOF
133133
)
134+
135+
git clone fetch multiple-remotes
136+
(cd multiple-remotes
137+
git remote add other ../fetch && git fetch other
138+
git remote add with/two/slashes ../fetch && git fetch with/two/slashes
139+
git remote add with/two ../fetch && git fetch with/two
140+
141+
git checkout -b main --track origin/main
142+
git checkout -b other-main --track other/main
143+
)

Diff for: ‎gix/tests/reference/mod.rs

+27
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use gix::remote::Direction;
2+
13
mod log {
24

35
#[test]
@@ -17,6 +19,31 @@ mod log {
1719
);
1820
}
1921
}
22+
23+
#[test]
24+
fn remote_name() -> crate::Result {
25+
let repo = crate::named_subrepo_opts(
26+
"make_remote_config_repos.sh",
27+
"multiple-remotes",
28+
gix::open::Options::isolated(),
29+
)?;
30+
for (ref_name, expected_remote) in [
31+
("main", "origin"),
32+
("other-main", "other"),
33+
("refs/remotes/origin/main", "origin"),
34+
("refs/remotes/other/main", "other"),
35+
("with/two/slashes/main", "with/two/slashes"),
36+
("with/two/main", "with/two"),
37+
] {
38+
let r = repo.find_reference(ref_name)?;
39+
assert_eq!(
40+
r.remote_name(Direction::Fetch).map(|name| name.as_bstr().to_owned()),
41+
Some(expected_remote.into())
42+
);
43+
}
44+
Ok(())
45+
}
46+
2047
mod find {
2148
use gix_ref as refs;
2249
use gix_ref::{FullName, FullNameRef, Target};

0 commit comments

Comments
 (0)
Please sign in to comment.