@@ -13,7 +13,7 @@ use crate::util::{internal, CargoResult, GlobalContext};
13
13
use anyhow:: Context as _;
14
14
use cargo_util:: paths;
15
15
use filetime:: FileTime ;
16
- use gix:: bstr:: { ByteSlice , ByteVec } ;
16
+ use gix:: bstr:: ByteVec ;
17
17
use ignore:: gitignore:: GitignoreBuilder ;
18
18
use tracing:: { trace, warn} ;
19
19
use walkdir:: WalkDir ;
@@ -295,7 +295,7 @@ impl<'gctx> PathSource<'gctx> {
295
295
}
296
296
} ;
297
297
let manifest_path = gix:: path:: join_bstr_unix_pathsep (
298
- gix:: path:: into_bstr ( repo_relative_path) ,
298
+ gix:: path:: to_unix_separators_on_windows ( gix :: path :: into_bstr ( repo_relative_path) ) ,
299
299
"Cargo.toml" ,
300
300
) ;
301
301
if index. entry_index_by_path ( & manifest_path) . is_ok ( ) {
@@ -424,15 +424,8 @@ impl<'gctx> PathSource<'gctx> {
424
424
// symlink points to a directory.
425
425
let is_dir = is_dir. unwrap_or_else ( || file_path. is_dir ( ) ) ;
426
426
if is_dir {
427
- warn ! ( " found submodule {}" , file_path. display( ) ) ;
428
- let rel = file_path. strip_prefix ( root) ?;
429
- let rel = rel. to_str ( ) . ok_or_else ( || {
430
- anyhow:: format_err!( "invalid utf-8 filename: {}" , rel. display( ) )
431
- } ) ?;
432
- // Git submodules are currently only named through `/` path
433
- // separators, explicitly not `\` which windows uses. Who knew?
434
- let rel = rel. replace ( r"\" , "/" ) ;
435
- match repo. find_submodule ( & rel) . and_then ( |s| s. open ( ) ) {
427
+ warn ! ( " found directory {}" , file_path. display( ) ) ;
428
+ match git2:: Repository :: open ( & file_path) {
436
429
Ok ( repo) => {
437
430
let files = self . list_files_git ( pkg, & repo, filter) ?;
438
431
ret. extend ( files. into_iter ( ) ) ;
@@ -531,7 +524,7 @@ impl<'gctx> PathSource<'gctx> {
531
524
vec ! [ include, exclude]
532
525
} ;
533
526
534
- let mut delegate = Delegate :: new ( self , pkg, pkg_path, repo , root, filter) ?;
527
+ let mut delegate = Delegate :: new ( self , pkg, pkg_path, root, filter) ?;
535
528
repo. dirwalk (
536
529
& index,
537
530
pathspec,
@@ -568,7 +561,6 @@ impl<'gctx> PathSource<'gctx> {
568
561
pkg_path : & ' a Path ,
569
562
parent : & ' a PathSource < ' gctx > ,
570
563
paths : Vec < PathBuf > ,
571
- submodules_by_rela_path : Vec < ( gix:: bstr:: BString , gix:: Submodule < ' a > ) > ,
572
564
subpackages_found : Vec < PathBuf > ,
573
565
filter : & ' a dyn Fn ( & Path , bool ) -> bool ,
574
566
err : Option < anyhow:: Error > ,
@@ -595,27 +587,15 @@ impl<'gctx> PathSource<'gctx> {
595
587
parent : & ' a PathSource < ' gctx > ,
596
588
pkg : & ' a Package ,
597
589
pkg_path : & ' a Path ,
598
- repo : & ' a gix:: Repository ,
599
590
root : & ' a Path ,
600
591
filter : & ' a dyn Fn ( & Path , bool ) -> bool ,
601
592
) -> CargoResult < Self > {
602
- let submodules_by_rela_path: Vec < _ > = repo
603
- . submodules ( ) ?
604
- . into_iter ( )
605
- . flatten ( )
606
- . map ( |sm| {
607
- sm. path ( )
608
- . map ( |path| path. into_owned ( ) )
609
- . map ( |path| ( path, sm) )
610
- } )
611
- . collect :: < Result < _ , _ > > ( ) ?;
612
593
Ok ( Self {
613
594
root,
614
595
pkg,
615
596
pkg_path,
616
597
parent,
617
598
filter,
618
- submodules_by_rela_path,
619
599
paths : vec ! [ ] ,
620
600
subpackages_found : vec ! [ ] ,
621
601
err : None ,
@@ -661,19 +641,24 @@ impl<'gctx> PathSource<'gctx> {
661
641
return Ok ( ( ) ) ;
662
642
}
663
643
664
- let is_dir = entry. disk_kind . map_or ( false , |kind| kind. is_dir ( ) ) ;
665
- if entry. disk_kind == Some ( gix:: dir:: entry:: Kind :: Repository ) {
666
- match self
667
- . submodules_by_rela_path
668
- . binary_search_by ( |( sm_path, _) | {
669
- sm_path. as_bstr ( ) . cmp ( entry. rela_path . as_ref ( ) )
670
- } )
671
- . map ( |idx| self . submodules_by_rela_path [ idx] . 1 . open ( ) )
672
- {
673
- Ok ( Ok ( Some ( sm_repo) ) ) => {
644
+ let is_dir = entry. disk_kind . map_or ( false , |kind| {
645
+ if kind == gix:: dir:: entry:: Kind :: Symlink {
646
+ // Symlinks must be checked to see if they point to a directory
647
+ // we should traverse.
648
+ file_path. is_dir ( )
649
+ } else {
650
+ kind. is_dir ( )
651
+ }
652
+ } ) ;
653
+ if is_dir {
654
+ // This could be a submodule, or a sub-repository. In any case, we prefer to walk
655
+ // it with git-support to leverage ignored files and to avoid pulling in entire
656
+ // .git repositories.
657
+ match gix:: open_opts ( & file_path, gix:: open:: Options :: isolated ( ) ) {
658
+ Ok ( sub_repo) => {
674
659
let files =
675
660
self . parent
676
- . list_files_gix ( self . pkg , & sm_repo , self . filter ) ?;
661
+ . list_files_gix ( self . pkg , & sub_repo , self . filter ) ?;
677
662
self . paths . extend ( files) ;
678
663
}
679
664
_ => {
0 commit comments