Skip to content

Commit bf39748

Browse files
committed
Auto merge of #9383 - alexcrichton:revert-git-head, r=ehuss
[beta] Revert #9133, moving to git HEAD dependencies by default This PR reverts #9133 on the beta branch. The reason for this is that I would like to take some more time to investigate fixing #9352 and #9334. I think those should be relatively easy to fix but I would prefer to not be too rushed with the next release happening soon. We realized today in the cargo meeting that this revert is likely to not have a ton of impact. For any projects using the v3 lock file format they'll continue to use it successfully. For projects on stable still using v2 they remain unaffected. This will ideally simply give some more time to fix these issues on nightly.
2 parents d70308e + c1fdb4c commit bf39748

File tree

11 files changed

+309
-66
lines changed

11 files changed

+309
-66
lines changed

src/cargo/core/resolver/dep_cache.rs

+48
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ use crate::core::resolver::errors::describe_path;
1414
use crate::core::resolver::types::{ConflictReason, DepInfo, FeaturesSet};
1515
use crate::core::resolver::{ActivateError, ActivateResult, ResolveOpts};
1616
use crate::core::{Dependency, FeatureValue, PackageId, PackageIdSpec, Registry, Summary};
17+
use crate::core::{GitReference, SourceId};
1718
use crate::util::errors::{CargoResult, CargoResultExt};
1819
use crate::util::interning::InternedString;
20+
use crate::util::Config;
1921
use log::debug;
2022
use std::cmp::Ordering;
2123
use std::collections::{BTreeSet, HashMap, HashSet};
@@ -38,6 +40,10 @@ pub struct RegistryQueryer<'a> {
3840
>,
3941
/// all the cases we ended up using a supplied replacement
4042
used_replacements: HashMap<PackageId, Summary>,
43+
/// Where to print warnings, if configured.
44+
config: Option<&'a Config>,
45+
/// Sources that we've already wared about possibly colliding in the future.
46+
warned_git_collisions: HashSet<SourceId>,
4147
}
4248

4349
impl<'a> RegistryQueryer<'a> {
@@ -46,6 +52,7 @@ impl<'a> RegistryQueryer<'a> {
4652
replacements: &'a [(PackageIdSpec, Dependency)],
4753
try_to_use: &'a HashSet<PackageId>,
4854
minimal_versions: bool,
55+
config: Option<&'a Config>,
4956
) -> Self {
5057
RegistryQueryer {
5158
registry,
@@ -55,6 +62,8 @@ impl<'a> RegistryQueryer<'a> {
5562
registry_cache: HashMap::new(),
5663
summary_cache: HashMap::new(),
5764
used_replacements: HashMap::new(),
65+
config,
66+
warned_git_collisions: HashSet::new(),
5867
}
5968
}
6069

@@ -66,13 +75,52 @@ impl<'a> RegistryQueryer<'a> {
6675
self.used_replacements.get(&p)
6776
}
6877

78+
/// Issues a future-compatible warning targeted at removing reliance on
79+
/// unifying behavior between these two dependency directives:
80+
///
81+
/// ```toml
82+
/// [dependencies]
83+
/// a = { git = 'https://example.org/foo' }
84+
/// a = { git = 'https://example.org/foo', branch = 'master }
85+
/// ```
86+
///
87+
/// Historical versions of Cargo considered these equivalent but going
88+
/// forward we'd like to fix this. For more details see the comments in
89+
/// src/cargo/sources/git/utils.rs
90+
fn warn_colliding_git_sources(&mut self, id: SourceId) -> CargoResult<()> {
91+
let config = match self.config {
92+
Some(config) => config,
93+
None => return Ok(()),
94+
};
95+
let prev = match self.warned_git_collisions.replace(id) {
96+
Some(prev) => prev,
97+
None => return Ok(()),
98+
};
99+
match (id.git_reference(), prev.git_reference()) {
100+
(Some(GitReference::DefaultBranch), Some(GitReference::Branch(b)))
101+
| (Some(GitReference::Branch(b)), Some(GitReference::DefaultBranch))
102+
if b == "master" => {}
103+
_ => return Ok(()),
104+
}
105+
106+
config.shell().warn(&format!(
107+
"two git dependencies found for `{}` \
108+
where one uses `branch = \"master\"` and the other doesn't; \
109+
this will break in a future version of Cargo, so please \
110+
ensure the dependency forms are consistent",
111+
id.url(),
112+
))?;
113+
Ok(())
114+
}
115+
69116
/// Queries the `registry` to return a list of candidates for `dep`.
70117
///
71118
/// This method is the location where overrides are taken into account. If
72119
/// any candidates are returned which match an override then the override is
73120
/// applied by performing a second query for what the override should
74121
/// return.
75122
pub fn query(&mut self, dep: &Dependency) -> CargoResult<Rc<Vec<Summary>>> {
123+
self.warn_colliding_git_sources(dep.source_id())?;
76124
if let Some(out) = self.registry_cache.get(dep).cloned() {
77125
return Ok(out);
78126
}

src/cargo/core/resolver/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ pub fn resolve(
133133
Some(config) => config.cli_unstable().minimal_versions,
134134
None => false,
135135
};
136-
let mut registry = RegistryQueryer::new(registry, replacements, try_to_use, minimal_versions);
136+
let mut registry =
137+
RegistryQueryer::new(registry, replacements, try_to_use, minimal_versions, config);
137138
let cx = activate_deps_loop(cx, &mut registry, summaries, config)?;
138139

139140
let mut cksums = HashMap::new();

src/cargo/core/resolver/resolve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,6 @@ impl Default for ResolveVersion {
409409
/// file anyway so it takes the opportunity to bump the lock file version
410410
/// forward.
411411
fn default() -> ResolveVersion {
412-
ResolveVersion::V3
412+
ResolveVersion::V2
413413
}
414414
}

src/cargo/core/source/source_id.rs

+74-4
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,45 @@ impl Ord for SourceId {
394394

395395
// Sort first based on `kind`, deferring to the URL comparison below if
396396
// the kinds are equal.
397-
match self.inner.kind.cmp(&other.inner.kind) {
398-
Ordering::Equal => {}
399-
other => return other,
397+
match (&self.inner.kind, &other.inner.kind) {
398+
(SourceKind::Path, SourceKind::Path) => {}
399+
(SourceKind::Path, _) => return Ordering::Less,
400+
(_, SourceKind::Path) => return Ordering::Greater,
401+
402+
(SourceKind::Registry, SourceKind::Registry) => {}
403+
(SourceKind::Registry, _) => return Ordering::Less,
404+
(_, SourceKind::Registry) => return Ordering::Greater,
405+
406+
(SourceKind::LocalRegistry, SourceKind::LocalRegistry) => {}
407+
(SourceKind::LocalRegistry, _) => return Ordering::Less,
408+
(_, SourceKind::LocalRegistry) => return Ordering::Greater,
409+
410+
(SourceKind::Directory, SourceKind::Directory) => {}
411+
(SourceKind::Directory, _) => return Ordering::Less,
412+
(_, SourceKind::Directory) => return Ordering::Greater,
413+
414+
(SourceKind::Git(a), SourceKind::Git(b)) => {
415+
use GitReference::*;
416+
let ord = match (a, b) {
417+
(Tag(a), Tag(b)) => a.cmp(b),
418+
(Tag(_), _) => Ordering::Less,
419+
(_, Tag(_)) => Ordering::Greater,
420+
421+
(Rev(a), Rev(b)) => a.cmp(b),
422+
(Rev(_), _) => Ordering::Less,
423+
(_, Rev(_)) => Ordering::Greater,
424+
425+
// See module comments in src/cargo/sources/git/utils.rs
426+
// for why `DefaultBranch` is treated specially here.
427+
(Branch(a), DefaultBranch) => a.as_str().cmp("master"),
428+
(DefaultBranch, Branch(b)) => "master".cmp(b),
429+
(Branch(a), Branch(b)) => a.cmp(b),
430+
(DefaultBranch, DefaultBranch) => Ordering::Equal,
431+
};
432+
if ord != Ordering::Equal {
433+
return ord;
434+
}
435+
}
400436
}
401437

402438
// If the `kind` and the `url` are equal, then for git sources we also
@@ -473,9 +509,43 @@ impl fmt::Display for SourceId {
473509
// The hash of SourceId is used in the name of some Cargo folders, so shouldn't
474510
// vary. `as_str` gives the serialisation of a url (which has a spec) and so
475511
// insulates against possible changes in how the url crate does hashing.
512+
//
513+
// Note that the semi-funky hashing here is done to handle `DefaultBranch`
514+
// hashing the same as `"master"`, and also to hash the same as previous
515+
// versions of Cargo while it's somewhat convenient to do so (that way all
516+
// versions of Cargo use the same checkout).
476517
impl Hash for SourceId {
477518
fn hash<S: hash::Hasher>(&self, into: &mut S) {
478-
self.inner.kind.hash(into);
519+
match &self.inner.kind {
520+
SourceKind::Git(GitReference::Tag(a)) => {
521+
0usize.hash(into);
522+
0usize.hash(into);
523+
a.hash(into);
524+
}
525+
SourceKind::Git(GitReference::Branch(a)) => {
526+
0usize.hash(into);
527+
1usize.hash(into);
528+
a.hash(into);
529+
}
530+
// For now hash `DefaultBranch` the same way as `Branch("master")`,
531+
// and for more details see module comments in
532+
// src/cargo/sources/git/utils.rs for why `DefaultBranch`
533+
SourceKind::Git(GitReference::DefaultBranch) => {
534+
0usize.hash(into);
535+
1usize.hash(into);
536+
"master".hash(into);
537+
}
538+
SourceKind::Git(GitReference::Rev(a)) => {
539+
0usize.hash(into);
540+
2usize.hash(into);
541+
a.hash(into);
542+
}
543+
544+
SourceKind::Path => 1usize.hash(into),
545+
SourceKind::Registry => 2usize.hash(into),
546+
SourceKind::LocalRegistry => 3usize.hash(into),
547+
SourceKind::Directory => 4usize.hash(into),
548+
}
479549
match self.inner.kind {
480550
SourceKind::Git(_) => self.inner.canonical_url.hash(into),
481551
_ => self.inner.url.as_str().hash(into),

src/cargo/ops/resolve.rs

+3-29
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@ use crate::core::registry::PackageRegistry;
1515
use crate::core::resolver::features::{
1616
FeatureOpts, FeatureResolver, ForceAllTargets, ResolvedFeatures,
1717
};
18-
use crate::core::resolver::{self, HasDevUnits, Resolve, ResolveOpts, ResolveVersion};
18+
use crate::core::resolver::{self, HasDevUnits, Resolve, ResolveOpts};
1919
use crate::core::summary::Summary;
2020
use crate::core::Feature;
21-
use crate::core::{
22-
GitReference, PackageId, PackageIdSpec, PackageSet, Source, SourceId, Workspace,
23-
};
21+
use crate::core::{PackageId, PackageIdSpec, PackageSet, Source, SourceId, Workspace};
2422
use crate::ops;
2523
use crate::sources::PathSource;
2624
use crate::util::errors::{CargoResult, CargoResultExt};
@@ -601,31 +599,7 @@ fn register_previous_locks(
601599
.deps_not_replaced(node)
602600
.map(|p| p.0)
603601
.filter(keep)
604-
.collect::<Vec<_>>();
605-
606-
// In the v2 lockfile format and prior the `branch=master` dependency
607-
// directive was serialized the same way as the no-branch-listed
608-
// directive. Nowadays in Cargo, however, these two directives are
609-
// considered distinct and are no longer represented the same way. To
610-
// maintain compatibility with older lock files we register locked nodes
611-
// for *both* the master branch and the default branch.
612-
//
613-
// Note that this is only applicable for loading older resolves now at
614-
// this point. All new lock files are encoded as v3-or-later, so this is
615-
// just compat for loading an old lock file successfully.
616-
if resolve.version() <= ResolveVersion::V2 {
617-
let source = node.source_id();
618-
if let Some(GitReference::DefaultBranch) = source.git_reference() {
619-
let new_source =
620-
SourceId::for_git(source.url(), GitReference::Branch("master".to_string()))
621-
.unwrap()
622-
.with_precise(source.precise().map(|s| s.to_string()));
623-
624-
let node = node.with_source_id(new_source);
625-
registry.register_lock(node, deps.clone());
626-
}
627-
}
628-
602+
.collect();
629603
registry.register_lock(node, deps);
630604
}
631605

src/cargo/sources/git/source.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,12 @@ impl<'cfg> Source for GitSource<'cfg> {
126126
// database, then try to resolve our reference with the preexisting
127127
// repository.
128128
(None, Some(db)) if self.config.offline() => {
129-
let rev = db.resolve(&self.manifest_reference).with_context(|| {
130-
"failed to lookup reference in preexisting repository, and \
129+
let rev = db
130+
.resolve(&self.manifest_reference, None)
131+
.with_context(|| {
132+
"failed to lookup reference in preexisting repository, and \
131133
can't check for updates in offline mode (--offline)"
132-
})?;
134+
})?;
133135
(db, rev)
134136
}
135137

0 commit comments

Comments
 (0)