Skip to content

Commit 5879852

Browse files
committed
refactor
1 parent d2cd2ef commit 5879852

File tree

4 files changed

+36
-25
lines changed

4 files changed

+36
-25
lines changed

gitoxide-core/src/repository/fetch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ pub(crate) mod function {
320320
err,
321321
"server sent {} tips, {} were filtered due to {} refspec(s).",
322322
map.remote_refs.len(),
323-
map.remote_refs.len() - map.mappings.len(),
323+
map.remote_refs.len().saturating_sub(map.mappings.len()),
324324
refspecs.len()
325325
)?;
326326
}

gix/src/clone/fetch/mod.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::{
22
bstr::{BString, ByteSlice},
33
clone::PrepareFetch,
44
};
5+
use gix_ref::Category;
56

67
/// The error returned by [`PrepareFetch::fetch_only()`].
78
#[derive(Debug, thiserror::Error)]
@@ -49,6 +50,8 @@ pub enum Error {
4950
CommitterOrFallback(#[from] crate::config::time::Error),
5051
#[error(transparent)]
5152
RefMap(#[from] crate::remote::ref_map::Error),
53+
#[error(transparent)]
54+
ReferenceName(#[from] gix_validate::reference::name::Error),
5255
}
5356

5457
/// Modification
@@ -106,15 +109,13 @@ impl PrepareFetch {
106109

107110
// For shallow clones without custom configuration, we'll use a single-branch refspec
108111
// to match git's behavior (matching git's single-branch behavior for shallow clones).
109-
let use_single_branch_for_shallow = self.shallow != remote::fetch::Shallow::NoChange
110-
&& self.configure_remote.is_none()
111-
&& remote.fetch_specs.is_empty();
112+
let use_single_branch_for_shallow =
113+
self.shallow != remote::fetch::Shallow::NoChange && remote.fetch_specs.is_empty();
112114

113115
let target_ref = if use_single_branch_for_shallow {
114116
// Determine target branch from user-specified ref_name or default branch
115117
if let Some(ref_name) = &self.ref_name {
116-
// User specified a branch, use that
117-
Some(format!("refs/heads/{}", ref_name.as_ref().as_bstr()))
118+
Some(Category::LocalBranch.to_full_name(ref_name.as_ref().as_bstr())?)
118119
} else {
119120
// For shallow clones without a specified ref, we need to determine the default branch.
120121
// We'll connect to get HEAD information. For Protocol V2, we need to explicitly list refs.
@@ -129,7 +130,7 @@ impl PrepareFetch {
129130
refs.iter().find_map(|r| match r {
130131
gix_protocol::handshake::Ref::Symbolic {
131132
full_ref_name, target, ..
132-
} if full_ref_name == "HEAD" => Some(target.to_string()),
133+
} if full_ref_name == "HEAD" => gix_ref::FullName::try_from(target).ok(),
133134
_ => None,
134135
})
135136
})
@@ -143,9 +144,9 @@ impl PrepareFetch {
143144
repo.config
144145
.resolved
145146
.string(crate::config::tree::Init::DEFAULT_BRANCH)
146-
.and_then(|name| name.to_str().ok().map(|s| format!("refs/heads/{}", s)))
147+
.and_then(|name| Category::LocalBranch.to_full_name(name.as_bstr()).ok())
147148
})
148-
.unwrap_or_else(|| "refs/heads/main".to_string());
149+
.unwrap_or_else(|| gix_ref::FullName::try_from("refs/heads/main").expect("known to be valid"));
149150

150151
// Drop the connection explicitly to release the borrow on remote
151152
drop(connection);
@@ -156,11 +157,12 @@ impl PrepareFetch {
156157
None
157158
};
158159

159-
// Set up refspec based on whether we're doing a single-branch shallow clone
160+
// Set up refspec based on whether we're doing a single-branch shallow clone,
161+
// which requires a single ref to match Git unless it's overridden.
160162
if remote.fetch_specs.is_empty() {
161163
if let Some(target_ref) = &target_ref {
162164
// Single-branch refspec for shallow clones
163-
let short_name = target_ref.strip_prefix("refs/heads/").unwrap_or(target_ref.as_str());
165+
let short_name = target_ref.shorten();
164166
remote = remote
165167
.with_refspecs(
166168
Some(format!("+{target_ref}:refs/remotes/{remote_name}/{short_name}").as_str()),

gix/src/config/tree/sections/init.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55

66
impl Init {
77
/// The `init.defaultBranch` key.
8+
// TODO: review its usage for cases where this key is not set - sometimes it's 'master', sometimes it's 'main'.
89
pub const DEFAULT_BRANCH: keys::Any = keys::Any::new("defaultBranch", &config::Tree::INIT)
910
.with_deviation("If not set, we use `main` instead of `master`");
1011
}

gix/tests/gix/clone.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ use crate::{remote, util::restricted};
44
mod blocking_io {
55
use std::{borrow::Cow, path::Path, sync::atomic::AtomicBool};
66

7+
use crate::{
8+
remote,
9+
util::{hex_to_id, restricted},
10+
};
711
use gix::{
812
bstr::BString,
913
config::tree::{Clone, Core, Init, Key},
@@ -14,11 +18,7 @@ mod blocking_io {
1418
};
1519
use gix_object::bstr::ByteSlice;
1620
use gix_ref::TargetRef;
17-
18-
use crate::{
19-
remote,
20-
util::{hex_to_id, restricted},
21-
};
21+
use gix_refspec::parse::Operation;
2222

2323
#[test]
2424
fn fetch_shallow_no_checkout_then_unshallow() -> crate::Result {
@@ -104,15 +104,14 @@ mod blocking_io {
104104

105105
// The refspec should be for a single branch (main), not a wildcard
106106
let refspec_str = refspecs[0].to_str().expect("valid utf8");
107-
assert!(
108-
!refspec_str.contains("*"),
109-
"shallow clone refspec should not use wildcard: {}",
110-
refspec_str
111-
);
112-
assert!(
113-
refspec_str.contains("refs/heads/main"),
114-
"shallow clone refspec should reference the main branch: {}",
115-
refspec_str
107+
assert_eq!(
108+
refspec_str,
109+
if cfg!(windows) {
110+
"+refs/heads/master:refs/remotes/origin/master"
111+
} else {
112+
"+refs/heads/main:refs/remotes/origin/main"
113+
},
114+
"shallow clone refspec should not use wildcard and should be the main branch: {refspec_str}"
116115
);
117116

118117
Ok(())
@@ -238,7 +237,16 @@ mod blocking_io {
238237
fn from_non_shallow_by_deepen_exclude_then_deepen_to_unshallow() -> crate::Result {
239238
let tmp = gix_testtools::tempfile::TempDir::new()?;
240239
let excluded_leaf_refs = ["g", "h", "j"];
240+
241241
let (repo, _change) = gix::prepare_clone_bare(remote::repo("base").path(), tmp.path())?
242+
.with_fetch_options(gix::remote::ref_map::Options {
243+
extra_refspecs: vec![gix::refspec::parse(
244+
"refs/heads/*:refs/remotes/origin/*".into(),
245+
Operation::Fetch,
246+
)?
247+
.into()],
248+
..Default::default()
249+
})
242250
.with_shallow(Shallow::Exclude {
243251
remote_refs: excluded_leaf_refs
244252
.into_iter()

0 commit comments

Comments
 (0)