-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Cache submodule into git db #16246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Cache submodule into git db #16246
Changes from all commits
69eeb23
ffd78e6
65cb3b7
3530ca4
ea4eb86
d4d3e6a
aeda351
8705c44
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,12 @@ | ||
| //! Utilities for handling git repositories, mainly around | ||
| //! authentication/cloning. | ||
|
|
||
| use crate::core::{GitReference, Verbosity}; | ||
| use crate::core::{GitReference, SourceId, Verbosity}; | ||
| use crate::sources::git::fetch::RemoteKind; | ||
| use crate::sources::git::oxide; | ||
| use crate::sources::git::oxide::cargo_config_to_gitoxide_overrides; | ||
| use crate::sources::git::source::GitSource; | ||
| use crate::sources::source::Source as _; | ||
| use crate::util::HumanBytes; | ||
| use crate::util::errors::{CargoResult, GitCliError}; | ||
| use crate::util::{GlobalContext, IntoUrl, MetricsCounter, Progress, network}; | ||
|
|
@@ -169,6 +171,7 @@ impl GitDatabase { | |
| rev: git2::Oid, | ||
| dest: &Path, | ||
| gctx: &GlobalContext, | ||
| quiet: bool, | ||
| ) -> CargoResult<GitCheckout<'_>> { | ||
| // If the existing checkout exists, and it is fresh, use it. | ||
| // A non-fresh checkout can happen if the checkout operation was | ||
|
|
@@ -182,7 +185,7 @@ impl GitDatabase { | |
| Some(co) => co, | ||
| None => { | ||
| let (checkout, guard) = GitCheckout::clone_into(dest, self, rev, gctx)?; | ||
| checkout.update_submodules(gctx)?; | ||
| checkout.update_submodules(gctx, quiet)?; | ||
| guard.mark_ok()?; | ||
| checkout | ||
| } | ||
|
|
@@ -384,24 +387,27 @@ impl<'a> GitCheckout<'a> { | |
| /// Submodules set to `none` won't be fetched. | ||
| /// | ||
| /// [^1]: <https://git-scm.com/docs/git-submodule#Documentation/git-submodule.txt-none> | ||
| fn update_submodules(&self, gctx: &GlobalContext) -> CargoResult<()> { | ||
| return update_submodules(&self.repo, gctx, self.remote_url().as_str()); | ||
| fn update_submodules(&self, gctx: &GlobalContext, quiet: bool) -> CargoResult<()> { | ||
| return update_submodules(&self.repo, gctx, quiet, self.remote_url().as_str()); | ||
|
|
||
| /// Recursive helper for [`GitCheckout::update_submodules`]. | ||
| fn update_submodules( | ||
| repo: &git2::Repository, | ||
| gctx: &GlobalContext, | ||
| quiet: bool, | ||
| parent_remote_url: &str, | ||
| ) -> CargoResult<()> { | ||
| debug!("update submodules for: {:?}", repo.workdir().unwrap()); | ||
|
|
||
| for mut child in repo.submodules()? { | ||
| update_submodule(repo, &mut child, gctx, parent_remote_url).with_context(|| { | ||
| format!( | ||
| "failed to update submodule `{}`", | ||
| child.name().unwrap_or("") | ||
| ) | ||
| })?; | ||
| update_submodule(repo, &mut child, gctx, quiet, parent_remote_url).with_context( | ||
| || { | ||
| format!( | ||
| "failed to update submodule `{}`", | ||
| child.name().unwrap_or("") | ||
| ) | ||
| }, | ||
| )?; | ||
| } | ||
| Ok(()) | ||
| } | ||
|
|
@@ -411,6 +417,7 @@ impl<'a> GitCheckout<'a> { | |
| parent: &git2::Repository, | ||
| child: &mut git2::Submodule<'_>, | ||
| gctx: &GlobalContext, | ||
| quiet: bool, | ||
| parent_remote_url: &str, | ||
| ) -> CargoResult<()> { | ||
| child.init(false)?; | ||
|
|
@@ -447,10 +454,10 @@ impl<'a> GitCheckout<'a> { | |
| let target = repo.head()?.target(); | ||
| Ok((target, repo)) | ||
| }); | ||
| let mut repo = match head_and_repo { | ||
| let repo = match head_and_repo { | ||
| Ok((head, repo)) => { | ||
| if child.head_id() == head { | ||
| return update_submodules(&repo, gctx, &child_remote_url); | ||
| return update_submodules(&repo, gctx, quiet, &child_remote_url); | ||
| } | ||
| repo | ||
| } | ||
|
|
@@ -460,25 +467,33 @@ impl<'a> GitCheckout<'a> { | |
| init(&path, false)? | ||
| } | ||
| }; | ||
| // Fetch data from origin and reset to the head commit | ||
| let reference = GitReference::Rev(head.to_string()); | ||
| gctx.shell() | ||
| .status("Updating", format!("git submodule `{child_remote_url}`"))?; | ||
| fetch( | ||
| &mut repo, | ||
| &child_remote_url, | ||
| &reference, | ||
| // Fetch data using git database | ||
| let mut source = GitSource::new( | ||
| SourceId::from_url(&format!("git+{child_remote_url}#{head}"))?, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of constructing URL manually, we have a |
||
| gctx, | ||
| RemoteKind::GitDependency, | ||
| ) | ||
| .with_context(|| { | ||
| let name = child.name().unwrap_or(""); | ||
| format!("failed to fetch submodule `{name}` from {child_remote_url}",) | ||
| })?; | ||
| source.set_quiet(quiet); | ||
|
|
||
| let (db, actual_rev) = source.update_db(true).with_context(|| { | ||
| let name = child.name().unwrap_or(""); | ||
| format!("failed to fetch submodule `{name}` from {child_remote_url}",) | ||
| })?; | ||
|
|
||
| // Clone and reset to the head commit | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are open to rebasing/reorganizing your commit history throughout the iterations of a pull request. And personally I think this kind of commit should be squashed into wherever made this typo. That would help get a more understandable/traceable git commit history |
||
| let (_, guard) = GitCheckout::clone_into(&repo.path(), &db, actual_rev, gctx) | ||
| .with_context(|| { | ||
| let name = child.name().unwrap_or(""); | ||
| format!("failed to fetch submodule `{name}` from {child_remote_url}",) | ||
| })?; | ||
| guard.mark_ok()?; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The checkout is marked ready then we recurse into submodules. I feel like that means the checkout is not ready yet. Would this situation happens? _User cancels the operation before recursing to nested submodules. They later they dependency on this submodule directly and Cargo assumes it is fresh so never recurse into nested submodules. |
||
|
|
||
| let obj = repo.find_object(head, None)?; | ||
| reset(&repo, &obj, gctx)?; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we still need this |
||
| update_submodules(&repo, gctx, &child_remote_url) | ||
| update_submodules(&repo, gctx, quiet, &child_remote_url) | ||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[not specific to this file]
[not hard blockers]
I noticed that in the commit history we have
Merge branch 'master' of https://…. We encourage rebasing and having a well-structured git history for review/debugging/tracing purpose.Also,
chore: …were used in some commits, butchoreshould have not production code change (see https://stackoverflow.com/a/26944812). IMO they should either berefactororfix.(Some may be better being squashed into the entire fix ffd78e6, as those intermediates commits minimally help future review and code tracing)