@@ -34,8 +34,8 @@ import (
34
34
// like Mercurial, Git, or Subversion.
35
35
type Cmd struct {
36
36
Name string
37
- Cmd string // name of binary to invoke command
38
- RootNames []string // filename indicating the root of a checkout directory
37
+ Cmd string // name of binary to invoke command
38
+ RootNames []rootName // filename and mode indicating the root of a checkout directory
39
39
40
40
CreateCmd []string // commands to download a fresh copy of a repository
41
41
DownloadCmd []string // commands to download updates into an existing repository
@@ -150,9 +150,11 @@ func vcsByCmd(cmd string) *Cmd {
150
150
151
151
// vcsHg describes how to use Mercurial.
152
152
var vcsHg = & Cmd {
153
- Name : "Mercurial" ,
154
- Cmd : "hg" ,
155
- RootNames : []string {".hg" },
153
+ Name : "Mercurial" ,
154
+ Cmd : "hg" ,
155
+ RootNames : []rootName {
156
+ {filename : ".hg" , isDir : true },
157
+ },
156
158
157
159
CreateCmd : []string {"clone -U -- {repo} {dir}" },
158
160
DownloadCmd : []string {"pull" },
@@ -238,9 +240,11 @@ func parseRevTime(out []byte) (string, time.Time, error) {
238
240
239
241
// vcsGit describes how to use Git.
240
242
var vcsGit = & Cmd {
241
- Name : "Git" ,
242
- Cmd : "git" ,
243
- RootNames : []string {".git" },
243
+ Name : "Git" ,
244
+ Cmd : "git" ,
245
+ RootNames : []rootName {
246
+ {filename : ".git" , isDir : true },
247
+ },
244
248
245
249
CreateCmd : []string {"clone -- {repo} {dir}" , "-go-internal-cd {dir} submodule update --init --recursive" },
246
250
DownloadCmd : []string {"pull --ff-only" , "submodule update --init --recursive" },
@@ -352,9 +356,11 @@ func gitStatus(vcsGit *Cmd, rootDir string) (Status, error) {
352
356
353
357
// vcsBzr describes how to use Bazaar.
354
358
var vcsBzr = & Cmd {
355
- Name : "Bazaar" ,
356
- Cmd : "bzr" ,
357
- RootNames : []string {".bzr" },
359
+ Name : "Bazaar" ,
360
+ Cmd : "bzr" ,
361
+ RootNames : []rootName {
362
+ {filename : ".bzr" , isDir : true },
363
+ },
358
364
359
365
CreateCmd : []string {"branch -- {repo} {dir}" },
360
366
@@ -473,9 +479,11 @@ func bzrStatus(vcsBzr *Cmd, rootDir string) (Status, error) {
473
479
474
480
// vcsSvn describes how to use Subversion.
475
481
var vcsSvn = & Cmd {
476
- Name : "Subversion" ,
477
- Cmd : "svn" ,
478
- RootNames : []string {".svn" },
482
+ Name : "Subversion" ,
483
+ Cmd : "svn" ,
484
+ RootNames : []rootName {
485
+ {filename : ".svn" , isDir : true },
486
+ },
479
487
480
488
CreateCmd : []string {"checkout -- {repo} {dir}" },
481
489
DownloadCmd : []string {"update" },
@@ -524,9 +532,12 @@ const fossilRepoName = ".fossil"
524
532
525
533
// vcsFossil describes how to use Fossil (fossil-scm.org)
526
534
var vcsFossil = & Cmd {
527
- Name : "Fossil" ,
528
- Cmd : "fossil" ,
529
- RootNames : []string {".fslckout" , "_FOSSIL_" },
535
+ Name : "Fossil" ,
536
+ Cmd : "fossil" ,
537
+ RootNames : []rootName {
538
+ {filename : ".fslckout" , isDir : false },
539
+ {filename : "_FOSSIL_" , isDir : false },
540
+ },
530
541
531
542
CreateCmd : []string {"-go-internal-mkdir {dir} clone -- {repo} " + filepath .Join ("{dir}" , fossilRepoName ), "-go-internal-cd {dir} open .fossil" },
532
543
DownloadCmd : []string {"up" },
@@ -814,7 +825,7 @@ func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cm
814
825
origDir := dir
815
826
for len (dir ) > len (srcRoot ) {
816
827
for _ , vcs := range vcsList {
817
- if _ , err := statAny (dir , vcs .RootNames ); err == nil {
828
+ if isVCSRoot (dir , vcs .RootNames ) {
818
829
// Record first VCS we find.
819
830
// If allowNesting is false (as it is in GOPATH), keep looking for
820
831
// repositories in parent directories and report an error if one is
@@ -827,10 +838,6 @@ func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cm
827
838
}
828
839
continue
829
840
}
830
- // Allow .git inside .git, which can arise due to submodules.
831
- if vcsCmd == vcs && vcs .Cmd == "git" {
832
- continue
833
- }
834
841
// Otherwise, we have one VCS inside a different VCS.
835
842
return "" , nil , fmt .Errorf ("directory %q uses %s, but parent %q uses %s" ,
836
843
repoDir , vcsCmd .Cmd , dir , vcs .Cmd )
@@ -850,23 +857,22 @@ func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cm
850
857
return repoDir , vcsCmd , nil
851
858
}
852
859
853
- // statAny provides FileInfo for the first filename found in the directory.
854
- // Otherwise, it returns the last error seen.
855
- func statAny (dir string , filenames []string ) (os.FileInfo , error ) {
856
- if len (filenames ) == 0 {
857
- return nil , errors .New ("invalid argument: no filenames provided" )
858
- }
859
-
860
- var err error
861
- var fi os.FileInfo
862
- for _ , name := range filenames {
863
- fi , err = os .Stat (filepath .Join (dir , name ))
864
- if err == nil {
865
- return fi , nil
860
+ // isVCSRoot identifies a VCS root by checking whether the directory contains
861
+ // any of the listed root names.
862
+ func isVCSRoot (dir string , rootNames []rootName ) bool {
863
+ for _ , root := range rootNames {
864
+ fi , err := os .Stat (filepath .Join (dir , root .filename ))
865
+ if err == nil && fi .IsDir () == root .isDir {
866
+ return true
866
867
}
867
868
}
868
869
869
- return nil , err
870
+ return false
871
+ }
872
+
873
+ type rootName struct {
874
+ filename string
875
+ isDir bool
870
876
}
871
877
872
878
type vcsNotFoundError struct {
@@ -1026,15 +1032,11 @@ func CheckNested(vcs *Cmd, dir, srcRoot string) error {
1026
1032
otherDir := dir
1027
1033
for len (otherDir ) > len (srcRoot ) {
1028
1034
for _ , otherVCS := range vcsList {
1029
- if _ , err := statAny (otherDir , otherVCS .RootNames ); err == nil {
1035
+ if isVCSRoot (otherDir , otherVCS .RootNames ) {
1030
1036
// Allow expected vcs in original dir.
1031
1037
if otherDir == dir && otherVCS == vcs {
1032
1038
continue
1033
1039
}
1034
- // Allow .git inside .git, which can arise due to submodules.
1035
- if otherVCS == vcs && vcs .Cmd == "git" {
1036
- continue
1037
- }
1038
1040
// Otherwise, we have one VCS inside a different VCS.
1039
1041
return fmt .Errorf ("directory %q uses %s, but parent %q uses %s" , dir , vcs .Cmd , otherDir , otherVCS .Cmd )
1040
1042
}
0 commit comments