8
8
"bytes"
9
9
"errors"
10
10
"fmt"
11
+ "internal/godebug"
11
12
"internal/lazyregexp"
12
13
"internal/singleflight"
13
14
"io/fs"
@@ -869,11 +870,13 @@ type vcsPath struct {
869
870
schemelessRepo bool // if true, the repo pattern lacks a scheme
870
871
}
871
872
873
+ var allowmultiplevcs = godebug .New ("allowmultiplevcs" )
874
+
872
875
// FromDir inspects dir and its parents to determine the
873
876
// version control system and code repository to use.
874
877
// If no repository is found, FromDir returns an error
875
878
// equivalent to os.ErrNotExist.
876
- func FromDir (dir , srcRoot string , allowNesting bool ) (repoDir string , vcsCmd * Cmd , err error ) {
879
+ func FromDir (dir , srcRoot string ) (repoDir string , vcsCmd * Cmd , err error ) {
877
880
// Clean and double-check that dir is in (a subdirectory of) srcRoot.
878
881
dir = filepath .Clean (dir )
879
882
if srcRoot != "" {
@@ -887,21 +890,28 @@ func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cm
887
890
for len (dir ) > len (srcRoot ) {
888
891
for _ , vcs := range vcsList {
889
892
if isVCSRoot (dir , vcs .RootNames ) {
890
- // Record first VCS we find.
891
- // If allowNesting is false (as it is in GOPATH), keep looking for
892
- // repositories in parent directories and report an error if one is
893
- // found to mitigate VCS injection attacks.
894
893
if vcsCmd == nil {
894
+ // Record first VCS we find.
895
895
vcsCmd = vcs
896
896
repoDir = dir
897
- if allowNesting {
897
+ if allowmultiplevcs .Value () == "1" {
898
+ allowmultiplevcs .IncNonDefault ()
898
899
return repoDir , vcsCmd , nil
899
900
}
901
+ // If allowmultiplevcs is not set, keep looking for
902
+ // repositories in current and parent directories and report
903
+ // an error if one is found to mitigate VCS injection
904
+ // attacks.
905
+ continue
906
+ }
907
+ if vcsCmd == vcsGit && vcs == vcsGit {
908
+ // Nested Git is allowed, as this is how things like
909
+ // submodules work. Git explicitly protects against
910
+ // injection against itself.
900
911
continue
901
912
}
902
- // Otherwise, we have one VCS inside a different VCS.
903
- return "" , nil , fmt .Errorf ("directory %q uses %s, but parent %q uses %s" ,
904
- repoDir , vcsCmd .Cmd , dir , vcs .Cmd )
913
+ return "" , nil , fmt .Errorf ("multiple VCS detected: %s in %q, and %s in %q" ,
914
+ vcsCmd .Cmd , repoDir , vcs .Cmd , dir )
905
915
}
906
916
}
907
917
0 commit comments