Skip to content

Commit 4f02e47

Browse files
avnyuweihanglo
authored andcommitted
feat: recursive cache git submodules
fetch each submodules using git database then checkout
1 parent 9e9d3db commit 4f02e47

2 files changed

Lines changed: 26 additions & 21 deletions

File tree

src/cargo/sources/git/utils.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
//! Utilities for handling git repositories, mainly around
22
//! authentication/cloning.
33
4-
use crate::core::{GitReference, Verbosity};
4+
use crate::core::{GitReference, SourceId, Verbosity};
55
use crate::sources::git::fetch::RemoteKind;
66
use crate::sources::git::oxide;
77
use crate::sources::git::oxide::cargo_config_to_gitoxide_overrides;
8+
use crate::sources::git::source::GitSource;
9+
use crate::sources::source::Source as _;
810
use crate::util::HumanBytes;
911
use crate::util::errors::{CargoResult, GitCliError};
1012
use crate::util::{GlobalContext, IntoUrl, MetricsCounter, Progress, network};
@@ -447,7 +449,7 @@ impl<'a> GitCheckout<'a> {
447449
let target = repo.head()?.target();
448450
Ok((target, repo))
449451
});
450-
let mut repo = match head_and_repo {
452+
let repo = match head_and_repo {
451453
Ok((head, repo)) => {
452454
if child.head_id() == head {
453455
return update_submodules(&repo, gctx, &child_remote_url);
@@ -460,25 +462,25 @@ impl<'a> GitCheckout<'a> {
460462
init(&path, false)?
461463
}
462464
};
463-
// Fetch data from origin and reset to the head commit
465+
// Fetch submodule database and checkout to target revision
464466
let reference = GitReference::Rev(head.to_string());
465467
gctx.shell()
466468
.status("Updating", format!("git submodule `{child_remote_url}`"))?;
467-
fetch(
468-
&mut repo,
469-
&child_remote_url,
470-
&reference,
471-
gctx,
472-
RemoteKind::GitDependency,
473-
)
474-
.with_context(|| {
469+
470+
// GitSource created from SourceId without git precise will result to
471+
// locked_rev being Deferred and fetch_db always try to fetch if online
472+
let source_id = SourceId::for_git(&child_remote_url.into_url()?, reference)?
473+
.with_git_precise(Some(head.to_string()));
474+
475+
let mut source = GitSource::new(source_id, gctx)?;
476+
source.set_quiet(true);
477+
478+
let (db, actual_rev) = source.fetch_db().with_context(|| {
475479
let name = child.name().unwrap_or("");
476480
format!("failed to fetch submodule `{name}` from {child_remote_url}",)
477481
})?;
478-
479-
let obj = repo.find_object(head, None)?;
480-
reset(&repo, &obj, gctx)?;
481-
update_submodules(&repo, gctx, &child_remote_url)
482+
db.copy_to(actual_rev, repo.path(), gctx)?;
483+
Ok(())
482484
}
483485
}
484486
}

tests/testsuite/git.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ fn dep_with_submodule() {
924924
.unwrap()
925925
.map(Result::unwrap)
926926
.collect::<Vec<_>>();
927-
assert_eq!(db_paths.len(), 0, "submodule db created once");
927+
assert_eq!(db_paths.len(), 1, "submodule db created once");
928928
}
929929

930930
#[cargo_test]
@@ -1005,7 +1005,7 @@ fn dep_with_relative_submodule() {
10051005
.unwrap()
10061006
.map(Result::unwrap)
10071007
.collect::<Vec<_>>();
1008-
assert_eq!(db_paths.len(), 0, "submodule db created once");
1008+
assert_eq!(db_paths.len(), 1, "submodule db created once");
10091009
}
10101010

10111011
#[cargo_test]
@@ -1077,7 +1077,10 @@ Caused by:
10771077
failed to update submodule `src`
10781078
10791079
Caused by:
1080-
object not found - no match for id ([..]); class=Odb (9); code=NotFound (-3)
1080+
failed to fetch submodule `src` from [ROOTURL]/dep2
1081+
1082+
Caused by:
1083+
revspec '[..]' not found; class=Reference (4); code=NotFound (-3)
10811084
10821085
"#]];
10831086

@@ -1539,7 +1542,7 @@ project2
15391542
.unwrap()
15401543
.map(Result::unwrap)
15411544
.collect::<Vec<_>>();
1542-
assert_eq!(db_paths.len(), 0, "submodule db created once");
1545+
assert_eq!(db_paths.len(), 1, "submodule db created once");
15431546

15441547
git_project.change_file(
15451548
".gitmodules",
@@ -1587,7 +1590,7 @@ project2
15871590
.unwrap()
15881591
.map(Result::unwrap)
15891592
.collect::<Vec<_>>();
1590-
assert_eq!(db_paths.len(), 0, "submodule db created once");
1593+
assert_eq!(db_paths.len(), 1, "submodule db created once");
15911594

15921595
println!("last run");
15931596
p.cargo("run")
@@ -4372,5 +4375,5 @@ fn dep_with_cached_submodule() {
43724375
.unwrap()
43734376
.map(Result::unwrap)
43744377
.collect::<Vec<_>>();
4375-
assert_eq!(db_paths.len(), 0, "submodule db created once");
4378+
assert_eq!(db_paths.len(), 1, "submodule db created once");
43764379
}

0 commit comments

Comments
 (0)