Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/cargo/sources/git/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,9 @@ impl<'gctx> GitSource<'gctx> {
trace!("updating git source `{:?}`", self.remote);

let locked_rev = locked_rev.clone().into();
self.remote.checkout(&db_path, db, &locked_rev, self.gctx)?
let manifest_reference = self.source_id.git_reference().unwrap();
self.remote
.checkout(&db_path, db, manifest_reference, &locked_rev, self.gctx)?
}
};
Ok((db, actual_rev))
Expand Down
16 changes: 13 additions & 3 deletions src/cargo/sources/git/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,15 @@ impl GitRemote {
&self,
into: &Path,
db: Option<GitDatabase>,
manifest_reference: &GitReference,
reference: &GitReference,
gctx: &GlobalContext,
) -> CargoResult<(GitDatabase, git2::Oid)> {
if let Some(mut db) = db {
fetch(
&mut db.repo,
self.url(),
manifest_reference,
reference,
gctx,
RemoteKind::GitDependency,
Expand All @@ -138,6 +140,7 @@ impl GitRemote {
fetch(
&mut repo,
self.url(),
manifest_reference,
reference,
gctx,
RemoteKind::GitDependency,
Expand Down Expand Up @@ -993,7 +996,8 @@ pub fn with_fetch_options(
pub fn fetch(
repo: &mut git2::Repository,
remote_url: &str,
reference: &GitReference,
manifest_reference: &GitReference,
locked_reference: &GitReference,
gctx: &GlobalContext,
remote_kind: RemoteKind,
) -> CargoResult<()> {
Expand All @@ -1009,7 +1013,7 @@ pub fn fetch(
// Flag to keep track if the rev is a full commit hash
let mut fast_path_rev: bool = false;

let oid_to_fetch = match github_fast_path(repo, remote_url, reference, gctx) {
let oid_to_fetch = match github_fast_path(repo, remote_url, locked_reference, gctx) {
Ok(FastPathRev::UpToDate) => return Ok(()),
Ok(FastPathRev::NeedsFetch(rev)) => Some(rev),
Ok(FastPathRev::Indeterminate) => None,
Expand All @@ -1030,7 +1034,7 @@ pub fn fetch(
// The `+` symbol on the refspec means to allow a forced (fast-forward)
// update which is needed if there is ever a force push that requires a
// fast-forward.
match reference {
match locked_reference {
// For branches and tags we can fetch simply one reference and copy it
// locally, no need to fetch other branches/tags.
GitReference::Branch(b) => {
Expand Down Expand Up @@ -1061,6 +1065,12 @@ pub fn fetch(
// The reason we write to `refs/remotes/origin/HEAD` is that it's of special significance
// when during `GitReference::resolve()`, but otherwise it shouldn't matter.
refspecs.push(format!("+{0}:refs/remotes/origin/HEAD", rev));
} else if let GitReference::Rev(rev) = manifest_reference
&& rev.starts_with("refs/")
{
// If the lockfile has a commit. we can't directly fetch it (unless we're talking
// to GitHub), so we fetch the ref associated with it from the manifest.
refspecs.push(format!("+{0}:{0}", rev));
} else {
// We don't know what the rev will point to. To handle this
// situation we fetch all branches and tags, and then we pray
Expand Down
1 change: 1 addition & 0 deletions src/cargo/sources/registry/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ impl<'gctx> RegistryData for RemoteRegistry<'gctx> {
repo,
url.as_str(),
&self.index_git_ref,
&self.index_git_ref,
self.gctx,
RemoteKind::Registry,
)
Expand Down
35 changes: 32 additions & 3 deletions tests/testsuite/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,20 @@ fn cargo_compile_git_dep_pull_request() {

// Make a reference in GitHub's pull request ref naming convention.
let repo = git2::Repository::open(&git_project.root()).unwrap();
let oid = repo.refname_to_id("HEAD").unwrap();
let force = false;
let log_message = "open pull request";
repo.reference("refs/pull/330/head", oid, force, log_message)
let parent = repo.head().unwrap().peel_to_commit().unwrap();
let author = repo.signature().unwrap();
let oid = repo
.commit(
None,
&author,
&author,
log_message,
&parent.tree().unwrap(),
&[&parent],
)
.unwrap();
repo.reference("refs/pull/330/head", oid, false, log_message)
.unwrap();

let project = project
Expand Down Expand Up @@ -290,6 +300,25 @@ fn cargo_compile_git_dep_pull_request() {
.run();

assert!(project.bin("foo").is_file());

// Delete the local cache, but keep the Cargo.lock to prevent regression
// of <https://github.com/rust-lang/cargo/issues/16767>
// This ensures we fetch the refs/pull/330/head spec explicitly, even
// if we have a locked commit.
paths::cargo_home().join("git").rm_rf();

project
.cargo("check")
.env("CARGO_NET_GIT_FETCH_WITH_CLI", "true")
.with_stderr_data(str![[r#"
[UPDATING] git repository `[ROOTURL]/dep1`
...
[CHECKING] dep1 v0.5.0 ([ROOTURL]/dep1?rev=refs%2Fpull%2F330%2Fhead#[..])
[CHECKING] foo v0.0.0 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]])
.run();
}

#[cargo_test]
Expand Down