@@ -734,16 +734,21 @@ public Map<String, Date> getLastModifiedTimes(File directory) throws CacheExcept
734
734
}
735
735
736
736
/**
737
- * recursively search for repositories with a depth limit, add those found to the internally used map.
737
+ * Recursively search for repositories with a depth limit, add those found to the internally used map.
738
+ * @see #putRepository(Repository)
738
739
*
739
- * @param files list of files to check if they contain a repository
740
+ * @param files list of directories to check if they contain a repository
740
741
* @param allowedNesting number of levels of nested repos to allow
741
- * @param depth current depth - using global scanningDepth - one can limit this to improve scanning performance
742
+ * @param depth maximum scanning depth
742
743
* @param isNested a value indicating if a parent {@link Repository} was already found above the {@code files}
743
744
* @return collection of added repositories
744
745
*/
745
746
private Collection <RepositoryInfo > addRepositories (File [] files , int allowedNesting , int depth , boolean isNested ) {
746
747
748
+ if (depth < 0 ) {
749
+ throw new IllegalArgumentException ("depth is negative" );
750
+ }
751
+
747
752
List <RepositoryInfo > repoList = new ArrayList <>();
748
753
PathAccepter pathAccepter = env .getPathAccepter ();
749
754
@@ -772,27 +777,28 @@ private Collection<RepositoryInfo> addRepositories(File[] files, int allowedNest
772
777
new Object [] {file , e .getMessage ()});
773
778
continue ;
774
779
}
780
+
775
781
if (repository == null ) {
776
- if (depth > env . getScanningDepth () ) {
777
- // we reached our search max depth, skip looking through the children
782
+ if (depth == 0 ) {
783
+ // Reached maximum depth, skip looking through the children.
778
784
continue ;
779
785
}
786
+
780
787
// Not a repository, search its sub-dirs.
781
788
if (pathAccepter .accept (file )) {
782
789
File [] subFiles = file .listFiles ();
783
790
if (subFiles == null ) {
784
791
LOGGER .log (Level .WARNING ,
785
- "Failed to get sub directories for ''{0}'', " +
786
- "check access permissions." ,
792
+ "Failed to get sub directories for ''{0}'', check access permissions." ,
787
793
file .getAbsolutePath ());
788
794
} else {
789
795
// Recursive call to scan next depth
790
796
repoList .addAll (addRepositories (subFiles ,
791
- allowedNesting , depth + 1 , isNested ));
797
+ allowedNesting , depth - 1 , isNested ));
792
798
}
793
799
}
794
800
} else {
795
- LOGGER .log (Level .CONFIG , "Adding <{0}> repository: < {1}> " ,
801
+ LOGGER .log (Level .CONFIG , "Adding <{0}> repository for '' {1}'' " ,
796
802
new Object []{repository .getClass ().getName (), path });
797
803
798
804
repoList .add (new RepositoryInfo (repository ));
@@ -804,17 +810,15 @@ private Collection<RepositoryInfo> addRepositories(File[] files, int allowedNest
804
810
LOGGER .log (Level .WARNING ,
805
811
"Failed to get sub directories for ''{0}'', check access permissions." ,
806
812
file .getAbsolutePath ());
807
- } else if (depth <= env .getScanningDepth ()) {
808
- // Search down to a limit -- if not: too much
809
- // stat'ing for huge Mercurial repositories
813
+ } else if (depth > 0 ) {
810
814
repoList .addAll (addRepositories (subFiles ,
811
- allowedNesting - 1 , depth + 1 , true ));
815
+ allowedNesting - 1 , depth - 1 , true ));
812
816
}
813
817
}
814
818
}
815
819
} catch (IOException exp ) {
816
820
LOGGER .log (Level .WARNING ,
817
- "Failed to get canonical path for {0}: {1}" ,
821
+ "Failed to get canonical path for '' {0}'' : {1}" ,
818
822
new Object []{file .getAbsolutePath (), exp .getMessage ()});
819
823
LOGGER .log (Level .WARNING , "Repository will be ignored..." , exp );
820
824
}
@@ -824,21 +828,36 @@ private Collection<RepositoryInfo> addRepositories(File[] files, int allowedNest
824
828
}
825
829
826
830
/**
827
- * Recursively search for repositories in given directories, add those found
828
- * to the internally used repository map.
831
+ * Recursively search for repositories in given directories, add those found to the internally used map.
829
832
*
830
833
* @param files list of directories to check if they contain a repository
831
834
* @return collection of added repositories
832
835
*/
833
836
public Collection <RepositoryInfo > addRepositories (File [] files ) {
834
837
ExecutorService executor = env .getIndexerParallelizer ().getFixedExecutor ();
835
838
List <Future <Collection <RepositoryInfo >>> futures = new ArrayList <>();
839
+ List <RepositoryInfo > repoList = new ArrayList <>();
840
+
836
841
for (File file : files ) {
842
+ /*
843
+ * Adjust scan depth based on source root path. Some directories can be symbolic links pointing
844
+ * outside source root so avoid constructing canonical paths for the computation to work.
845
+ */
846
+ int levelsBelowSourceRoot ;
847
+ try {
848
+ String relativePath = env .getPathRelativeToSourceRoot (file );
849
+ levelsBelowSourceRoot = Path .of (relativePath ).getNameCount ();
850
+ } catch (IOException | ForbiddenSymlinkException e ) {
851
+ LOGGER .log (Level .WARNING , "cannot get path relative to source root for ''{0}'', " +
852
+ "skipping repository scan for this directory" , file );
853
+ continue ;
854
+ }
855
+ final int scanDepth = env .getScanningDepth () - levelsBelowSourceRoot ;
856
+
837
857
futures .add (executor .submit (() -> addRepositories (new File []{file },
838
- env .getNestingMaximum (), 0 , false )));
858
+ env .getNestingMaximum (), scanDepth , false )));
839
859
}
840
860
841
- List <RepositoryInfo > repoList = new ArrayList <>();
842
861
futures .forEach (future -> {
843
862
try {
844
863
repoList .addAll (future .get ());
@@ -853,23 +872,21 @@ public Collection<RepositoryInfo> addRepositories(File[] files) {
853
872
}
854
873
855
874
/**
856
- * Recursively search for repositories in given directories, add those found
857
- * to the internally used repository map.
875
+ * Recursively search for repositories in given directories, add those found to the internally used map.
858
876
*
859
877
* @param repos collection of repository paths
860
- * @return collection of added repositories
878
+ * @return collection of {@link RepositoryInfo} objects
861
879
*/
862
880
public Collection <RepositoryInfo > addRepositories (Collection <String > repos ) {
863
881
return addRepositories (repos .stream ().map (File ::new ).toArray (File []::new ));
864
882
}
865
883
866
884
/**
867
885
* Get collection of repositories used internally by HistoryGuru.
868
- * @return collection of repositories
886
+ * @return collection of {@link RepositoryInfo} objects
869
887
*/
870
888
public Collection <RepositoryInfo > getRepositories () {
871
- return repositories .values ().stream ().
872
- map (RepositoryInfo ::new ).collect (Collectors .toSet ());
889
+ return repositories .values ().stream ().map (RepositoryInfo ::new ).collect (Collectors .toSet ());
873
890
}
874
891
875
892
private void createHistoryCache (Repository repository , String sinceRevision ) {
0 commit comments