@@ -556,6 +556,13 @@ fn lock(locked: &LockedMap, patches: &HashMap<Url, Vec<PackageId>>, summary: Sum
556
556
// requirement has changed. In this case we must discard the
557
557
// locked version because the dependency needs to be
558
558
// re-resolved.
559
+ //
560
+ // 3. We don't have a lock entry for this dependency, in which
561
+ // case it was likely an optional dependency which wasn't
562
+ // included previously so we just pass it through anyway.
563
+ //
564
+ // Cases 1/2 are handled by `matches_id` and case 3 is handled by
565
+ // falling through to the logic below.
559
566
if let Some ( & ( _, ref locked_deps) ) = pair {
560
567
let locked = locked_deps. iter ( ) . find ( |id| dep. matches_id ( id) ) ;
561
568
if let Some ( locked) = locked {
@@ -566,6 +573,24 @@ fn lock(locked: &LockedMap, patches: &HashMap<Url, Vec<PackageId>>, summary: Sum
566
573
}
567
574
}
568
575
576
+ // Querying a git dependency has the side effect of pulling changes.
577
+ // So even the conservative re-resolution may be to aggressive.
578
+ // If this git dependency did not have a locked version, then we query
579
+ // all known locked packages to see if they match this dependency.
580
+ // If anything does then we lock it to that and move on.
581
+ if dep. source_id ( ) . git_reference ( ) . is_some ( ) {
582
+ let v = locked
583
+ . get ( dep. source_id ( ) )
584
+ . and_then ( |map| map. get ( & * dep. name ( ) ) )
585
+ . and_then ( |vec| vec. iter ( ) . find ( |& & ( ref id, _) | dep. matches_id ( id) ) ) ;
586
+ if let Some ( & ( ref id, _) ) = v {
587
+ trace ! ( "\t second hit on {}" , id) ;
588
+ let mut dep = dep. clone ( ) ;
589
+ dep. lock_to ( id) ;
590
+ return dep;
591
+ }
592
+ }
593
+
569
594
// Finally we check to see if any registered patches correspond to
570
595
// this dependency.
571
596
let v = patches. get ( dep. source_id ( ) . url ( ) ) . map ( |vec| {
0 commit comments