Skip to content

Commit d4b8fc6

Browse files
committed
Allow fetching a single object, shallow or not.
Doing so seems cleaner as there should be no logical difference between shallow or not-shallow when fetching. We want a specific object, and should get it with the refspec. `git` will assure we see all objects we need, handling shallow-ness for us. Note that one test needed adjustments due to the different mechanism used when fetching local repositories, requiring more changes to properly 'break' the submodule repo when `gitoxide` is used.
1 parent e20b020 commit d4b8fc6

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

src/cargo/sources/git/utils.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,6 @@ pub fn fetch(
855855

856856
// If we're fetching from GitHub, attempt GitHub's special fast path for
857857
// testing if we've already got an up-to-date copy of the repository.
858-
let is_shallow = !matches!(shallow, gix::remote::fetch::Shallow::NoChange);
859858
let oid_to_fetch = match github_fast_path(repo, orig_url, reference, config) {
860859
Ok(FastPathRev::UpToDate) => return Ok(()),
861860
Ok(FastPathRev::NeedsFetch(rev)) => Some(rev),
@@ -901,10 +900,10 @@ pub fn fetch(
901900
refspecs.push(format!("+{0}:{0}", rev));
902901
} else if let Some(oid_to_fetch) = oid_to_fetch {
903902
refspecs.push(format!("+{0}:refs/commit/{0}", oid_to_fetch));
904-
} else if is_shallow && rev.parse::<Oid>().is_ok() {
903+
} else if rev.parse::<Oid>().is_ok() {
905904
// There is a specific commit to fetch and we will just do so in shallow-mode only
906905
// to not disturb the previous logic. Note that with typical settings for shallowing,
907-
// With shallow histories this is a bit fuzzy, and we opt-out for now.
906+
// we will just fetch a single `rev` as single commit.
908907
refspecs.push(format!("+{0}:refs/remotes/origin/HEAD", rev));
909908
} else {
910909
// We don't know what the rev will point to. To handle this

tests/testsuite/git.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,13 @@ fn dep_with_bad_submodule() {
948948
None,
949949
)
950950
.unwrap();
951+
std::fs::remove_file(
952+
repo.path()
953+
.join("objects")
954+
.join(&commit.id().to_string()[..2])
955+
.join(&commit.id().to_string()[2..]),
956+
)
957+
.unwrap();
951958

952959
let p = project
953960
.file(
@@ -972,9 +979,36 @@ fn dep_with_bad_submodule() {
972979
"extern crate dep1; pub fn foo() { dep1::dep() }",
973980
)
974981
.build();
982+
let expected = if cargo_uses_gitoxide() {
983+
format!(
984+
"\
985+
[UPDATING] git repository [..]
986+
[UPDATING] git submodule `file://[..]/dep2`
987+
[ERROR] failed to get `dep1` as a dependency of package `foo v0.5.0 [..]`
988+
989+
Caused by:
990+
failed to load source for dependency `dep1`
991+
992+
Caused by:
993+
Unable to update {}
994+
995+
Caused by:
996+
failed to update submodule `src`
975997
976-
let expected = format!(
977-
"\
998+
Caused by:
999+
failed to fetch submodule `src` from [..]
1000+
1001+
Caused by:
1002+
Could not decode server reply
1003+
1004+
Caused by:
1005+
upload-pack: not our ref [..]
1006+
",
1007+
path2url(git_project.root())
1008+
)
1009+
} else {
1010+
format!(
1011+
"\
9781012
[UPDATING] git repository [..]
9791013
[UPDATING] git submodule `file://[..]/dep2`
9801014
[ERROR] failed to get `dep1` as a dependency of package `foo v0.5.0 [..]`
@@ -989,10 +1023,14 @@ Caused by:
9891023
failed to update submodule `src`
9901024
9911025
Caused by:
992-
object not found - no match for id [..]
1026+
failed to fetch submodule `src` from [..]
1027+
1028+
Caused by:
1029+
target OID for the reference doesn't exist on the repository; class=Reference (4)
9931030
",
994-
path2url(git_project.root())
995-
);
1031+
path2url(git_project.root())
1032+
)
1033+
};
9961034

9971035
p.cargo("check")
9981036
.with_stderr(expected)

0 commit comments

Comments
 (0)