From ebae2dcdbabadfdb9880a627481eaf0079a08767 Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Wed, 4 Oct 2017 22:43:55 -0400 Subject: [PATCH] go/vcs: reject update of VCS inside VCS Manually apply same change as CL 68110 did for cmd/go/internal/get, but for golang.org/x/tools/go/vcs, to help keep them in sync. Updates golang/go#22125. Helps golang/go#11490. Change-Id: I255f7a494d9572389fc8dc8ce96891b6fcc214a0 Reviewed-on: https://go-review.googlesource.com/68352 Reviewed-by: Russ Cox --- go/vcs/vcs.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/go/vcs/vcs.go b/go/vcs/vcs.go index 3c56a950..1c87793b 100644 --- a/go/vcs/vcs.go +++ b/go/vcs/vcs.go @@ -344,11 +344,28 @@ func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error) { return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot) } + var vcsRet *Cmd + var rootRet string + origDir := dir for len(dir) > len(srcRoot) { for _, vcs := range vcsList { if _, err := os.Stat(filepath.Join(dir, "."+vcs.Cmd)); err == nil { - return vcs, filepath.ToSlash(dir[len(srcRoot)+1:]), nil + root := filepath.ToSlash(dir[len(srcRoot)+1:]) + // Record first VCS we find, but keep looking, + // to detect mistakes like one kind of VCS inside another. + if vcsRet == nil { + vcsRet = vcs + rootRet = root + continue + } + // Allow .git inside .git, which can arise due to submodules. + if vcsRet == vcs && vcs.Cmd == "git" { + continue + } + // Otherwise, we have one VCS inside a different VCS. + return nil, "", fmt.Errorf("directory %q uses %s, but parent %q uses %s", + filepath.Join(srcRoot, rootRet), vcsRet.Cmd, filepath.Join(srcRoot, root), vcs.Cmd) } } @@ -361,6 +378,10 @@ func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error) { dir = ndir } + if vcsRet != nil { + return vcsRet, rootRet, nil + } + return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir) }