diff --git a/README.md b/README.md
index 0a2fcf1..4dbf6d6 100644
--- a/README.md
+++ b/README.md
@@ -62,12 +62,11 @@
 
 Numerous other packages provide more esoteric functionality.
 
-<!-- Some that didn't make the cut: 
+<!-- Some that didn't make the cut:
 
 golang.org/x/tools/benchmark/parse
 golang.org/x/tools/go/ast/astutil
 golang.org/x/tools/go/types/typeutil
-golang.org/x/tools/go/vcs
 golang.org/x/tools/playground
 golang.org/x/tools/present
 golang.org/x/tools/refactor/importgraph
diff --git a/go/vcs/discovery.go b/go/vcs/discovery.go
deleted file mode 100644
index 7d179bc..0000000
--- a/go/vcs/discovery.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vcs
-
-import (
-	"encoding/xml"
-	"fmt"
-	"io"
-	"strings"
-)
-
-// charsetReader returns a reader for the given charset. Currently
-// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
-// error which is printed by go get, so the user can find why the package
-// wasn't downloaded if the encoding is not supported. Note that, in
-// order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
-// greater than 0x7f are not rejected).
-func charsetReader(charset string, input io.Reader) (io.Reader, error) {
-	switch strings.ToLower(charset) {
-	case "ascii":
-		return input, nil
-	default:
-		return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
-	}
-}
-
-// parseMetaGoImports returns meta imports from the HTML in r.
-// Parsing ends at the end of the <head> section or the beginning of the <body>.
-//
-// This copy of cmd/go/internal/vcs.parseMetaGoImports always operates
-// in IgnoreMod ModuleMode.
-func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
-	d := xml.NewDecoder(r)
-	d.CharsetReader = charsetReader
-	d.Strict = false
-	var t xml.Token
-	for {
-		t, err = d.RawToken()
-		if err != nil {
-			if err == io.EOF || len(imports) > 0 {
-				err = nil
-			}
-			return
-		}
-		if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
-			return
-		}
-		if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
-			return
-		}
-		e, ok := t.(xml.StartElement)
-		if !ok || !strings.EqualFold(e.Name.Local, "meta") {
-			continue
-		}
-		if attrValue(e.Attr, "name") != "go-import" {
-			continue
-		}
-		if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
-			// Ignore VCS type "mod", which is applicable only in module mode.
-			if f[1] == "mod" {
-				continue
-			}
-			imports = append(imports, metaImport{
-				Prefix:   f[0],
-				VCS:      f[1],
-				RepoRoot: f[2],
-			})
-		}
-	}
-}
-
-// attrValue returns the attribute value for the case-insensitive key
-// `name', or the empty string if nothing is found.
-func attrValue(attrs []xml.Attr, name string) string {
-	for _, a := range attrs {
-		if strings.EqualFold(a.Name.Local, name) {
-			return a.Value
-		}
-	}
-	return ""
-}
diff --git a/go/vcs/env.go b/go/vcs/env.go
deleted file mode 100644
index 189210c..0000000
--- a/go/vcs/env.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vcs
-
-import (
-	"os"
-	"strings"
-)
-
-// envForDir returns a copy of the environment
-// suitable for running in the given directory.
-// The environment is the current process's environment
-// but with an updated $PWD, so that an os.Getwd in the
-// child will be faster.
-func envForDir(dir string) []string {
-	env := os.Environ()
-	// Internally we only use rooted paths, so dir is rooted.
-	// Even if dir is not rooted, no harm done.
-	return mergeEnvLists([]string{"PWD=" + dir}, env)
-}
-
-// mergeEnvLists merges the two environment lists such that
-// variables with the same name in "in" replace those in "out".
-func mergeEnvLists(in, out []string) []string {
-NextVar:
-	for _, inkv := range in {
-		k := strings.SplitAfterN(inkv, "=", 2)[0]
-		for i, outkv := range out {
-			if strings.HasPrefix(outkv, k) {
-				out[i] = inkv
-				continue NextVar
-			}
-		}
-		out = append(out, inkv)
-	}
-	return out
-}
diff --git a/go/vcs/go.mod b/go/vcs/go.mod
deleted file mode 100644
index 74da6cb..0000000
--- a/go/vcs/go.mod
+++ /dev/null
@@ -1,7 +0,0 @@
-// Deprecated: This module contains one deprecated package.
-// See the package deprecation notice for more information.
-module golang.org/x/tools/go/vcs
-
-go 1.19
-
-require golang.org/x/sys v0.9.0
diff --git a/go/vcs/go.sum b/go/vcs/go.sum
deleted file mode 100644
index cb35c1f..0000000
--- a/go/vcs/go.sum
+++ /dev/null
@@ -1,2 +0,0 @@
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/go/vcs/http.go b/go/vcs/http.go
deleted file mode 100644
index 5836511..0000000
--- a/go/vcs/http.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vcs
-
-import (
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"net/url"
-)
-
-// httpClient is the default HTTP client, but a variable so it can be
-// changed by tests, without modifying http.DefaultClient.
-var httpClient = http.DefaultClient
-
-// httpGET returns the data from an HTTP GET request for the given URL.
-func httpGET(url string) ([]byte, error) {
-	resp, err := httpClient.Get(url)
-	if err != nil {
-		return nil, err
-	}
-	defer resp.Body.Close()
-	if resp.StatusCode != 200 {
-		return nil, fmt.Errorf("%s: %s", url, resp.Status)
-	}
-	b, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, fmt.Errorf("%s: %v", url, err)
-	}
-	return b, nil
-}
-
-// httpsOrHTTP returns the body of either the importPath's
-// https resource or, if unavailable, the http resource.
-func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err error) {
-	fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
-		u, err := url.Parse(scheme + "://" + importPath)
-		if err != nil {
-			return "", nil, err
-		}
-		u.RawQuery = "go-get=1"
-		urlStr = u.String()
-		if Verbose {
-			log.Printf("Fetching %s", urlStr)
-		}
-		res, err = httpClient.Get(urlStr)
-		return
-	}
-	closeBody := func(res *http.Response) {
-		if res != nil {
-			res.Body.Close()
-		}
-	}
-	urlStr, res, err := fetch("https")
-	if err != nil || res.StatusCode != 200 {
-		if Verbose {
-			if err != nil {
-				log.Printf("https fetch failed.")
-			} else {
-				log.Printf("ignoring https fetch with status code %d", res.StatusCode)
-			}
-		}
-		closeBody(res)
-		urlStr, res, err = fetch("http")
-	}
-	if err != nil {
-		closeBody(res)
-		return "", nil, err
-	}
-	// Note: accepting a non-200 OK here, so people can serve a
-	// meta import in their http 404 page.
-	if Verbose {
-		log.Printf("Parsing meta tags from %s (status code %d)", urlStr, res.StatusCode)
-	}
-	return urlStr, res.Body, nil
-}
diff --git a/go/vcs/vcs.go b/go/vcs/vcs.go
deleted file mode 100644
index 232177d..0000000
--- a/go/vcs/vcs.go
+++ /dev/null
@@ -1,764 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package vcs exposes functions for resolving import paths
-// and using version control systems, which can be used to
-// implement behavior similar to the standard "go get" command.
-//
-// Deprecated: Use the go list command with -json flag instead,
-// which implements up-to-date import path resolution behavior,
-// module support, and includes the latest security fixes.
-//
-// This package was a copy of internal code in package cmd/go/internal/get
-// before module support, modified to make the identifiers exported.
-// It was provided here for developers who wanted to write tools with similar semantics.
-// It needed to be manually kept in sync with upstream when changes were
-// made to cmd/go/internal/get, as tracked in go.dev/issue/11490.
-// By now, it has diverged significantly from upstream cmd/go/internal/get
-// behavior and will not receive any further updates.
-package vcs // import "golang.org/x/tools/go/vcs"
-
-import (
-	"bytes"
-	"encoding/json"
-	"errors"
-	"fmt"
-	exec "golang.org/x/sys/execabs"
-	"log"
-	"net/url"
-	"os"
-	"path/filepath"
-	"regexp"
-	"strconv"
-	"strings"
-)
-
-// Verbose enables verbose operation logging.
-var Verbose bool
-
-// ShowCmd controls whether VCS commands are printed.
-var ShowCmd bool
-
-// A Cmd describes how to use a version control system
-// like Mercurial, Git, or Subversion.
-type Cmd struct {
-	Name string
-	Cmd  string // name of binary to invoke command
-
-	CreateCmd   string // command to download a fresh copy of a repository
-	DownloadCmd string // command to download updates into an existing repository
-
-	TagCmd         []TagCmd // commands to list tags
-	TagLookupCmd   []TagCmd // commands to lookup tags before running tagSyncCmd
-	TagSyncCmd     string   // command to sync to specific tag
-	TagSyncDefault string   // command to sync to default tag
-
-	LogCmd string // command to list repository changelogs in an XML format
-
-	Scheme  []string
-	PingCmd string
-}
-
-// A TagCmd describes a command to list available tags
-// that can be passed to Cmd.TagSyncCmd.
-type TagCmd struct {
-	Cmd     string // command to list tags
-	Pattern string // regexp to extract tags from list
-}
-
-// vcsList lists the known version control systems
-var vcsList = []*Cmd{
-	vcsHg,
-	vcsGit,
-	vcsSvn,
-	vcsBzr,
-}
-
-// ByCmd returns the version control system for the given
-// command name (hg, git, svn, bzr).
-func ByCmd(cmd string) *Cmd {
-	for _, vcs := range vcsList {
-		if vcs.Cmd == cmd {
-			return vcs
-		}
-	}
-	return nil
-}
-
-// vcsHg describes how to use Mercurial.
-var vcsHg = &Cmd{
-	Name: "Mercurial",
-	Cmd:  "hg",
-
-	CreateCmd:   "clone -U {repo} {dir}",
-	DownloadCmd: "pull",
-
-	// We allow both tag and branch names as 'tags'
-	// for selecting a version.  This lets people have
-	// a go.release.r60 branch and a go1 branch
-	// and make changes in both, without constantly
-	// editing .hgtags.
-	TagCmd: []TagCmd{
-		{"tags", `^(\S+)`},
-		{"branches", `^(\S+)`},
-	},
-	TagSyncCmd:     "update -r {tag}",
-	TagSyncDefault: "update default",
-
-	LogCmd: "log --encoding=utf-8 --limit={limit} --template={template}",
-
-	Scheme:  []string{"https", "http", "ssh"},
-	PingCmd: "identify {scheme}://{repo}",
-}
-
-// vcsGit describes how to use Git.
-var vcsGit = &Cmd{
-	Name: "Git",
-	Cmd:  "git",
-
-	CreateCmd:   "clone {repo} {dir}",
-	DownloadCmd: "pull --ff-only",
-
-	TagCmd: []TagCmd{
-		// tags/xxx matches a git tag named xxx
-		// origin/xxx matches a git branch named xxx on the default remote repository
-		{"show-ref", `(?:tags|origin)/(\S+)$`},
-	},
-	TagLookupCmd: []TagCmd{
-		{"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`},
-	},
-	TagSyncCmd:     "checkout {tag}",
-	TagSyncDefault: "checkout master",
-
-	Scheme:  []string{"git", "https", "http", "git+ssh"},
-	PingCmd: "ls-remote {scheme}://{repo}",
-}
-
-// vcsBzr describes how to use Bazaar.
-var vcsBzr = &Cmd{
-	Name: "Bazaar",
-	Cmd:  "bzr",
-
-	CreateCmd: "branch {repo} {dir}",
-
-	// Without --overwrite bzr will not pull tags that changed.
-	// Replace by --overwrite-tags after http://pad.lv/681792 goes in.
-	DownloadCmd: "pull --overwrite",
-
-	TagCmd:         []TagCmd{{"tags", `^(\S+)`}},
-	TagSyncCmd:     "update -r {tag}",
-	TagSyncDefault: "update -r revno:-1",
-
-	Scheme:  []string{"https", "http", "bzr", "bzr+ssh"},
-	PingCmd: "info {scheme}://{repo}",
-}
-
-// vcsSvn describes how to use Subversion.
-var vcsSvn = &Cmd{
-	Name: "Subversion",
-	Cmd:  "svn",
-
-	CreateCmd:   "checkout {repo} {dir}",
-	DownloadCmd: "update",
-
-	// There is no tag command in subversion.
-	// The branch information is all in the path names.
-
-	LogCmd: "log --xml --limit={limit}",
-
-	Scheme:  []string{"https", "http", "svn", "svn+ssh"},
-	PingCmd: "info {scheme}://{repo}",
-}
-
-func (v *Cmd) String() string {
-	return v.Name
-}
-
-// run runs the command line cmd in the given directory.
-// keyval is a list of key, value pairs.  run expands
-// instances of {key} in cmd into value, but only after
-// splitting cmd into individual arguments.
-// If an error occurs, run prints the command line and the
-// command's combined stdout+stderr to standard error.
-// Otherwise run discards the command's output.
-func (v *Cmd) run(dir string, cmd string, keyval ...string) error {
-	_, err := v.run1(dir, cmd, keyval, true)
-	return err
-}
-
-// runVerboseOnly is like run but only generates error output to standard error in verbose mode.
-func (v *Cmd) runVerboseOnly(dir string, cmd string, keyval ...string) error {
-	_, err := v.run1(dir, cmd, keyval, false)
-	return err
-}
-
-// runOutput is like run but returns the output of the command.
-func (v *Cmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) {
-	return v.run1(dir, cmd, keyval, true)
-}
-
-// run1 is the generalized implementation of run and runOutput.
-func (v *Cmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) {
-	m := make(map[string]string)
-	for i := 0; i < len(keyval); i += 2 {
-		m[keyval[i]] = keyval[i+1]
-	}
-	args := strings.Fields(cmdline)
-	for i, arg := range args {
-		args[i] = expand(m, arg)
-	}
-
-	_, err := exec.LookPath(v.Cmd)
-	if err != nil {
-		fmt.Fprintf(os.Stderr,
-			"go: missing %s command. See http://golang.org/s/gogetcmd\n",
-			v.Name)
-		return nil, err
-	}
-
-	cmd := exec.Command(v.Cmd, args...)
-	cmd.Dir = dir
-	cmd.Env = envForDir(cmd.Dir)
-	if ShowCmd {
-		fmt.Printf("cd %s\n", dir)
-		fmt.Printf("%s %s\n", v.Cmd, strings.Join(args, " "))
-	}
-	var buf bytes.Buffer
-	cmd.Stdout = &buf
-	cmd.Stderr = &buf
-	err = cmd.Run()
-	out := buf.Bytes()
-	if err != nil {
-		if verbose || Verbose {
-			fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.Cmd, strings.Join(args, " "))
-			os.Stderr.Write(out)
-		}
-		return nil, err
-	}
-	return out, nil
-}
-
-// Ping pings the repo to determine if scheme used is valid.
-// This repo must be pingable with this scheme and VCS.
-func (v *Cmd) Ping(scheme, repo string) error {
-	return v.runVerboseOnly(".", v.PingCmd, "scheme", scheme, "repo", repo)
-}
-
-// Create creates a new copy of repo in dir.
-// The parent of dir must exist; dir must not.
-func (v *Cmd) Create(dir, repo string) error {
-	return v.run(".", v.CreateCmd, "dir", dir, "repo", repo)
-}
-
-// CreateAtRev creates a new copy of repo in dir at revision rev.
-// The parent of dir must exist; dir must not.
-// rev must be a valid revision in repo.
-func (v *Cmd) CreateAtRev(dir, repo, rev string) error {
-	if err := v.Create(dir, repo); err != nil {
-		return err
-	}
-	return v.run(dir, v.TagSyncCmd, "tag", rev)
-}
-
-// Download downloads any new changes for the repo in dir.
-// dir must be a valid VCS repo compatible with v.
-func (v *Cmd) Download(dir string) error {
-	return v.run(dir, v.DownloadCmd)
-}
-
-// Tags returns the list of available tags for the repo in dir.
-// dir must be a valid VCS repo compatible with v.
-func (v *Cmd) Tags(dir string) ([]string, error) {
-	var tags []string
-	for _, tc := range v.TagCmd {
-		out, err := v.runOutput(dir, tc.Cmd)
-		if err != nil {
-			return nil, err
-		}
-		re := regexp.MustCompile(`(?m-s)` + tc.Pattern)
-		for _, m := range re.FindAllStringSubmatch(string(out), -1) {
-			tags = append(tags, m[1])
-		}
-	}
-	return tags, nil
-}
-
-// TagSync syncs the repo in dir to the named tag, which is either a
-// tag returned by Tags or the empty string (the default tag).
-// dir must be a valid VCS repo compatible with v and the tag must exist.
-func (v *Cmd) TagSync(dir, tag string) error {
-	if v.TagSyncCmd == "" {
-		return nil
-	}
-	if tag != "" {
-		for _, tc := range v.TagLookupCmd {
-			out, err := v.runOutput(dir, tc.Cmd, "tag", tag)
-			if err != nil {
-				return err
-			}
-			re := regexp.MustCompile(`(?m-s)` + tc.Pattern)
-			m := re.FindStringSubmatch(string(out))
-			if len(m) > 1 {
-				tag = m[1]
-				break
-			}
-		}
-	}
-	if tag == "" && v.TagSyncDefault != "" {
-		return v.run(dir, v.TagSyncDefault)
-	}
-	return v.run(dir, v.TagSyncCmd, "tag", tag)
-}
-
-// Log logs the changes for the repo in dir.
-// dir must be a valid VCS repo compatible with v.
-func (v *Cmd) Log(dir, logTemplate string) ([]byte, error) {
-	if err := v.Download(dir); err != nil {
-		return []byte{}, err
-	}
-
-	const N = 50 // how many revisions to grab
-	return v.runOutput(dir, v.LogCmd, "limit", strconv.Itoa(N), "template", logTemplate)
-}
-
-// LogAtRev logs the change for repo in dir at the rev revision.
-// dir must be a valid VCS repo compatible with v.
-// rev must be a valid revision for the repo in dir.
-func (v *Cmd) LogAtRev(dir, rev, logTemplate string) ([]byte, error) {
-	if err := v.Download(dir); err != nil {
-		return []byte{}, err
-	}
-
-	// Append revision flag to LogCmd.
-	logAtRevCmd := v.LogCmd + " --rev=" + rev
-	return v.runOutput(dir, logAtRevCmd, "limit", strconv.Itoa(1), "template", logTemplate)
-}
-
-// A vcsPath describes how to convert an import path into a
-// version control system and repository name.
-type vcsPath struct {
-	prefix string                              // prefix this description applies to
-	re     string                              // pattern for import path
-	repo   string                              // repository to use (expand with match of re)
-	vcs    string                              // version control system to use (expand with match of re)
-	check  func(match map[string]string) error // additional checks
-	ping   bool                                // ping for scheme to use to download repo
-
-	regexp *regexp.Regexp // cached compiled form of re
-}
-
-// FromDir inspects dir and its parents to determine the
-// version control system and code repository to use.
-// On return, root is the import path
-// corresponding to the root of the repository.
-func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error) {
-	// Clean and double-check that dir is in (a subdirectory of) srcRoot.
-	dir = filepath.Clean(dir)
-	srcRoot = filepath.Clean(srcRoot)
-	if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
-		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 {
-				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)
-			}
-		}
-
-		// Move to parent.
-		ndir := filepath.Dir(dir)
-		if len(ndir) >= len(dir) {
-			// Shouldn't happen, but just in case, stop.
-			break
-		}
-		dir = ndir
-	}
-
-	if vcsRet != nil {
-		return vcsRet, rootRet, nil
-	}
-
-	return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir)
-}
-
-// RepoRoot represents a version control system, a repo, and a root of
-// where to put it on disk.
-type RepoRoot struct {
-	VCS *Cmd
-
-	// Repo is the repository URL, including scheme.
-	Repo string
-
-	// Root is the import path corresponding to the root of the
-	// repository.
-	Root string
-}
-
-// RepoRootForImportPath analyzes importPath to determine the
-// version control system, and code repository to use.
-func RepoRootForImportPath(importPath string, verbose bool) (*RepoRoot, error) {
-	rr, err := RepoRootForImportPathStatic(importPath, "")
-	if err == errUnknownSite {
-		rr, err = RepoRootForImportDynamic(importPath, verbose)
-
-		// RepoRootForImportDynamic returns error detail
-		// that is irrelevant if the user didn't intend to use a
-		// dynamic import in the first place.
-		// Squelch it.
-		if err != nil {
-			if Verbose {
-				log.Printf("import %q: %v", importPath, err)
-			}
-			err = fmt.Errorf("unrecognized import path %q", importPath)
-		}
-	}
-
-	if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.Root, "...") {
-		// Do not allow wildcards in the repo root.
-		rr = nil
-		err = fmt.Errorf("cannot expand ... in %q", importPath)
-	}
-	return rr, err
-}
-
-var errUnknownSite = errors.New("dynamic lookup required to find mapping")
-
-// RepoRootForImportPathStatic attempts to map importPath to a
-// RepoRoot using the commonly-used VCS hosting sites in vcsPaths
-// (github.com/user/dir), or from a fully-qualified importPath already
-// containing its VCS type (foo.com/repo.git/dir)
-//
-// If scheme is non-empty, that scheme is forced.
-func RepoRootForImportPathStatic(importPath, scheme string) (*RepoRoot, error) {
-	if strings.Contains(importPath, "://") {
-		return nil, fmt.Errorf("invalid import path %q", importPath)
-	}
-	for _, srv := range vcsPaths {
-		if !strings.HasPrefix(importPath, srv.prefix) {
-			continue
-		}
-		m := srv.regexp.FindStringSubmatch(importPath)
-		if m == nil {
-			if srv.prefix != "" {
-				return nil, fmt.Errorf("invalid %s import path %q", srv.prefix, importPath)
-			}
-			continue
-		}
-
-		// Build map of named subexpression matches for expand.
-		match := map[string]string{
-			"prefix": srv.prefix,
-			"import": importPath,
-		}
-		for i, name := range srv.regexp.SubexpNames() {
-			if name != "" && match[name] == "" {
-				match[name] = m[i]
-			}
-		}
-		if srv.vcs != "" {
-			match["vcs"] = expand(match, srv.vcs)
-		}
-		if srv.repo != "" {
-			match["repo"] = expand(match, srv.repo)
-		}
-		if srv.check != nil {
-			if err := srv.check(match); err != nil {
-				return nil, err
-			}
-		}
-		vcs := ByCmd(match["vcs"])
-		if vcs == nil {
-			return nil, fmt.Errorf("unknown version control system %q", match["vcs"])
-		}
-		if srv.ping {
-			if scheme != "" {
-				match["repo"] = scheme + "://" + match["repo"]
-			} else {
-				for _, scheme := range vcs.Scheme {
-					if vcs.Ping(scheme, match["repo"]) == nil {
-						match["repo"] = scheme + "://" + match["repo"]
-						break
-					}
-				}
-			}
-		}
-		rr := &RepoRoot{
-			VCS:  vcs,
-			Repo: match["repo"],
-			Root: match["root"],
-		}
-		return rr, nil
-	}
-	return nil, errUnknownSite
-}
-
-// RepoRootForImportDynamic finds a *RepoRoot for a custom domain that's not
-// statically known by RepoRootForImportPathStatic.
-//
-// This handles custom import paths like "name.tld/pkg/foo" or just "name.tld".
-func RepoRootForImportDynamic(importPath string, verbose bool) (*RepoRoot, error) {
-	slash := strings.Index(importPath, "/")
-	if slash < 0 {
-		slash = len(importPath)
-	}
-	host := importPath[:slash]
-	if !strings.Contains(host, ".") {
-		return nil, errors.New("import path doesn't contain a hostname")
-	}
-	urlStr, body, err := httpsOrHTTP(importPath)
-	if err != nil {
-		return nil, fmt.Errorf("http/https fetch: %v", err)
-	}
-	defer body.Close()
-	imports, err := parseMetaGoImports(body)
-	if err != nil {
-		return nil, fmt.Errorf("parsing %s: %v", importPath, err)
-	}
-	metaImport, err := matchGoImport(imports, importPath)
-	if err != nil {
-		if err != errNoMatch {
-			return nil, fmt.Errorf("parse %s: %v", urlStr, err)
-		}
-		return nil, fmt.Errorf("parse %s: no go-import meta tags", urlStr)
-	}
-	if verbose {
-		log.Printf("get %q: found meta tag %#v at %s", importPath, metaImport, urlStr)
-	}
-	// If the import was "uni.edu/bob/project", which said the
-	// prefix was "uni.edu" and the RepoRoot was "evilroot.com",
-	// make sure we don't trust Bob and check out evilroot.com to
-	// "uni.edu" yet (possibly overwriting/preempting another
-	// non-evil student).  Instead, first verify the root and see
-	// if it matches Bob's claim.
-	if metaImport.Prefix != importPath {
-		if verbose {
-			log.Printf("get %q: verifying non-authoritative meta tag", importPath)
-		}
-		urlStr0 := urlStr
-		urlStr, body, err = httpsOrHTTP(metaImport.Prefix)
-		if err != nil {
-			return nil, fmt.Errorf("fetch %s: %v", urlStr, err)
-		}
-		imports, err := parseMetaGoImports(body)
-		if err != nil {
-			return nil, fmt.Errorf("parsing %s: %v", importPath, err)
-		}
-		if len(imports) == 0 {
-			return nil, fmt.Errorf("fetch %s: no go-import meta tag", urlStr)
-		}
-		metaImport2, err := matchGoImport(imports, importPath)
-		if err != nil || metaImport != metaImport2 {
-			return nil, fmt.Errorf("%s and %s disagree about go-import for %s", urlStr0, urlStr, metaImport.Prefix)
-		}
-	}
-
-	if err := validateRepoRoot(metaImport.RepoRoot); err != nil {
-		return nil, fmt.Errorf("%s: invalid repo root %q: %v", urlStr, metaImport.RepoRoot, err)
-	}
-	rr := &RepoRoot{
-		VCS:  ByCmd(metaImport.VCS),
-		Repo: metaImport.RepoRoot,
-		Root: metaImport.Prefix,
-	}
-	if rr.VCS == nil {
-		return nil, fmt.Errorf("%s: unknown vcs %q", urlStr, metaImport.VCS)
-	}
-	return rr, nil
-}
-
-// validateRepoRoot returns an error if repoRoot does not seem to be
-// a valid URL with scheme.
-func validateRepoRoot(repoRoot string) error {
-	url, err := url.Parse(repoRoot)
-	if err != nil {
-		return err
-	}
-	if url.Scheme == "" {
-		return errors.New("no scheme")
-	}
-	return nil
-}
-
-// metaImport represents the parsed <meta name="go-import"
-// content="prefix vcs reporoot" /> tags from HTML files.
-type metaImport struct {
-	Prefix, VCS, RepoRoot string
-}
-
-// errNoMatch is returned from matchGoImport when there's no applicable match.
-var errNoMatch = errors.New("no import match")
-
-// pathPrefix reports whether sub is a prefix of s,
-// only considering entire path components.
-func pathPrefix(s, sub string) bool {
-	// strings.HasPrefix is necessary but not sufficient.
-	if !strings.HasPrefix(s, sub) {
-		return false
-	}
-	// The remainder after the prefix must either be empty or start with a slash.
-	rem := s[len(sub):]
-	return rem == "" || rem[0] == '/'
-}
-
-// matchGoImport returns the metaImport from imports matching importPath.
-// An error is returned if there are multiple matches.
-// errNoMatch is returned if none match.
-func matchGoImport(imports []metaImport, importPath string) (_ metaImport, err error) {
-	match := -1
-	for i, im := range imports {
-		if !pathPrefix(importPath, im.Prefix) {
-			continue
-		}
-
-		if match != -1 {
-			err = fmt.Errorf("multiple meta tags match import path %q", importPath)
-			return
-		}
-		match = i
-	}
-	if match == -1 {
-		err = errNoMatch
-		return
-	}
-	return imports[match], nil
-}
-
-// expand rewrites s to replace {k} with match[k] for each key k in match.
-func expand(match map[string]string, s string) string {
-	for k, v := range match {
-		s = strings.Replace(s, "{"+k+"}", v, -1)
-	}
-	return s
-}
-
-// vcsPaths lists the known vcs paths.
-var vcsPaths = []*vcsPath{
-	// Github
-	{
-		prefix: "github.com/",
-		re:     `^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[\p{L}0-9_.\-]+)*$`,
-		vcs:    "git",
-		repo:   "https://{root}",
-		check:  noVCSSuffix,
-	},
-
-	// Bitbucket
-	{
-		prefix: "bitbucket.org/",
-		re:     `^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
-		repo:   "https://{root}",
-		check:  bitbucketVCS,
-	},
-
-	// Launchpad
-	{
-		prefix: "launchpad.net/",
-		re:     `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
-		vcs:    "bzr",
-		repo:   "https://{root}",
-		check:  launchpadVCS,
-	},
-
-	// Git at OpenStack
-	{
-		prefix: "git.openstack.org",
-		re:     `^(?P<root>git\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`,
-		vcs:    "git",
-		repo:   "https://{root}",
-		check:  noVCSSuffix,
-	},
-
-	// General syntax for any server.
-	{
-		re:   `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
-		ping: true,
-	},
-}
-
-func init() {
-	// fill in cached regexps.
-	// Doing this eagerly discovers invalid regexp syntax
-	// without having to run a command that needs that regexp.
-	for _, srv := range vcsPaths {
-		srv.regexp = regexp.MustCompile(srv.re)
-	}
-}
-
-// noVCSSuffix checks that the repository name does not
-// end in .foo for any version control system foo.
-// The usual culprit is ".git".
-func noVCSSuffix(match map[string]string) error {
-	repo := match["repo"]
-	for _, vcs := range vcsList {
-		if strings.HasSuffix(repo, "."+vcs.Cmd) {
-			return fmt.Errorf("invalid version control suffix in %s path", match["prefix"])
-		}
-	}
-	return nil
-}
-
-// bitbucketVCS determines the version control system for a
-// Bitbucket repository, by using the Bitbucket API.
-func bitbucketVCS(match map[string]string) error {
-	if err := noVCSSuffix(match); err != nil {
-		return err
-	}
-
-	var resp struct {
-		SCM string `json:"scm"`
-	}
-	url := expand(match, "https://api.bitbucket.org/2.0/repositories/{bitname}?fields=scm")
-	data, err := httpGET(url)
-	if err != nil {
-		return err
-	}
-	if err := json.Unmarshal(data, &resp); err != nil {
-		return fmt.Errorf("decoding %s: %v", url, err)
-	}
-
-	if ByCmd(resp.SCM) != nil {
-		match["vcs"] = resp.SCM
-		if resp.SCM == "git" {
-			match["repo"] += ".git"
-		}
-		return nil
-	}
-
-	return fmt.Errorf("unable to detect version control system for bitbucket.org/ path")
-}
-
-// launchpadVCS solves the ambiguity for "lp.net/project/foo". In this case,
-// "foo" could be a series name registered in Launchpad with its own branch,
-// and it could also be the name of a directory within the main project
-// branch one level up.
-func launchpadVCS(match map[string]string) error {
-	if match["project"] == "" || match["series"] == "" {
-		return nil
-	}
-	_, err := httpGET(expand(match, "https://code.launchpad.net/{project}{series}/.bzr/branch-format"))
-	if err != nil {
-		match["root"] = expand(match, "launchpad.net/{project}")
-		match["repo"] = expand(match, "https://{root}")
-	}
-	return nil
-}
diff --git a/go/vcs/vcs_test.go b/go/vcs/vcs_test.go
deleted file mode 100644
index a17b50d..0000000
--- a/go/vcs/vcs_test.go
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vcs
-
-import (
-	"errors"
-	"io/ioutil"
-	"os"
-	"path"
-	"path/filepath"
-	"reflect"
-	"runtime"
-	"strings"
-	"testing"
-)
-
-// Test that RepoRootForImportPath creates the correct RepoRoot for a given importPath.
-// TODO(cmang): Add tests for SVN and BZR.
-func TestRepoRootForImportPath(t *testing.T) {
-	if runtime.GOOS == "android" {
-		t.Skipf("incomplete source tree on %s", runtime.GOOS)
-	}
-
-	tests := []struct {
-		path string
-		want *RepoRoot
-	}{
-		{
-			"github.com/golang/groupcache",
-			&RepoRoot{
-				VCS:  vcsGit,
-				Repo: "https://github.com/golang/groupcache",
-			},
-		},
-		// Unicode letters in directories (issue 18660).
-		{
-			"github.com/user/unicode/испытание",
-			&RepoRoot{
-				VCS:  vcsGit,
-				Repo: "https://github.com/user/unicode",
-			},
-		},
-	}
-
-	for _, test := range tests {
-		got, err := RepoRootForImportPath(test.path, false)
-		if err != nil {
-			t.Errorf("RepoRootForImportPath(%q): %v", test.path, err)
-			continue
-		}
-		want := test.want
-		if got.VCS.Name != want.VCS.Name || got.Repo != want.Repo {
-			t.Errorf("RepoRootForImportPath(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.VCS, got.Repo, want.VCS, want.Repo)
-		}
-	}
-}
-
-// Test that FromDir correctly inspects a given directory and returns the right VCS and root.
-func TestFromDir(t *testing.T) {
-	tempDir, err := ioutil.TempDir("", "vcstest")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tempDir)
-
-	for j, vcs := range vcsList {
-		dir := filepath.Join(tempDir, "example.com", vcs.Name, "."+vcs.Cmd)
-		if j&1 == 0 {
-			err := os.MkdirAll(dir, 0755)
-			if err != nil {
-				t.Fatal(err)
-			}
-		} else {
-			err := os.MkdirAll(filepath.Dir(dir), 0755)
-			if err != nil {
-				t.Fatal(err)
-			}
-			f, err := os.Create(dir)
-			if err != nil {
-				t.Fatal(err)
-			}
-			f.Close()
-		}
-
-		want := RepoRoot{
-			VCS:  vcs,
-			Root: path.Join("example.com", vcs.Name),
-		}
-		var got RepoRoot
-		got.VCS, got.Root, err = FromDir(dir, tempDir)
-		if err != nil {
-			t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err)
-			continue
-		}
-		if got.VCS.Name != want.VCS.Name || got.Root != want.Root {
-			t.Errorf("FromDir(%q, %q) = VCS(%s) Root(%s), want VCS(%s) Root(%s)", dir, tempDir, got.VCS, got.Root, want.VCS, want.Root)
-		}
-	}
-}
-
-var parseMetaGoImportsTests = []struct {
-	in  string
-	out []metaImport
-}{
-	{
-		`<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
-		[]metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
-	},
-	{
-		`<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
-		<meta name="go-import" content="baz/quux git http://github.com/rsc/baz/quux">`,
-		[]metaImport{
-			{"foo/bar", "git", "https://github.com/rsc/foo/bar"},
-			{"baz/quux", "git", "http://github.com/rsc/baz/quux"},
-		},
-	},
-	{
-		`<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
-		<meta name="go-import" content="foo/bar mod http://github.com/rsc/baz/quux">`,
-		[]metaImport{
-			{"foo/bar", "git", "https://github.com/rsc/foo/bar"},
-		},
-	},
-	{
-		`<meta name="go-import" content="foo/bar mod http://github.com/rsc/baz/quux">
-		<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
-		[]metaImport{
-			{"foo/bar", "git", "https://github.com/rsc/foo/bar"},
-		},
-	},
-	{
-		`<head>
-		<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
-		</head>`,
-		[]metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
-	},
-	{
-		`<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
-		<body>`,
-		[]metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
-	},
-	{
-		`<!doctype html><meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
-		[]metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
-	},
-	{
-		// XML doesn't like <div style=position:relative>.
-		`<!doctype html><title>Page Not Found</title><meta name=go-import content="chitin.io/chitin git https://github.com/chitin-io/chitin"><div style=position:relative>DRAFT</div>`,
-		[]metaImport{{"chitin.io/chitin", "git", "https://github.com/chitin-io/chitin"}},
-	},
-	{
-		`<meta name="go-import" content="myitcv.io git https://github.com/myitcv/x">
-	        <meta name="go-import" content="myitcv.io/blah2 mod https://raw.githubusercontent.com/myitcv/pubx/master">
-	        `,
-		[]metaImport{{"myitcv.io", "git", "https://github.com/myitcv/x"}},
-	},
-}
-
-func TestParseMetaGoImports(t *testing.T) {
-	for i, tt := range parseMetaGoImportsTests {
-		out, err := parseMetaGoImports(strings.NewReader(tt.in))
-		if err != nil {
-			t.Errorf("test#%d: %v", i, err)
-			continue
-		}
-		if !reflect.DeepEqual(out, tt.out) {
-			t.Errorf("test#%d:\n\thave %q\n\twant %q", i, out, tt.out)
-		}
-	}
-}
-
-func TestValidateRepoRoot(t *testing.T) {
-	tests := []struct {
-		root string
-		ok   bool
-	}{
-		{
-			root: "",
-			ok:   false,
-		},
-		{
-			root: "http://",
-			ok:   true,
-		},
-		{
-			root: "git+ssh://",
-			ok:   true,
-		},
-		{
-			root: "http#://",
-			ok:   false,
-		},
-		{
-			root: "-config",
-			ok:   false,
-		},
-		{
-			root: "-config://",
-			ok:   false,
-		},
-	}
-
-	for _, test := range tests {
-		err := validateRepoRoot(test.root)
-		ok := err == nil
-		if ok != test.ok {
-			want := "error"
-			if test.ok {
-				want = "nil"
-			}
-			t.Errorf("validateRepoRoot(%q) = %q, want %s", test.root, err, want)
-		}
-	}
-}
-
-func TestMatchGoImport(t *testing.T) {
-	tests := []struct {
-		imports []metaImport
-		path    string
-		mi      metaImport
-		err     error
-	}{
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com/user/foo",
-			mi:   metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-		},
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com/user/foo/",
-			mi:   metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-		},
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-				{Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com/user/foo",
-			mi:   metaImport{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-		},
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-				{Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com/user/fooa",
-			mi:   metaImport{Prefix: "example.com/user/fooa", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-		},
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-				{Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com/user/foo/bar",
-			err:  errors.New("should not be allowed to create nested repo"),
-		},
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-				{Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com/user/foo/bar/baz",
-			err:  errors.New("should not be allowed to create nested repo"),
-		},
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-				{Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com/user/foo/bar/baz/qux",
-			err:  errors.New("should not be allowed to create nested repo"),
-		},
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-				{Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com/user/foo/bar/baz/",
-			err:  errors.New("should not be allowed to create nested repo"),
-		},
-		{
-			imports: []metaImport{
-				{Prefix: "example.com/user/foo", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-				{Prefix: "example.com/user/foo/bar", VCS: "git", RepoRoot: "https://example.com/repo/target"},
-			},
-			path: "example.com",
-			err:  errors.New("pathologically short path"),
-		},
-	}
-
-	for _, test := range tests {
-		mi, err := matchGoImport(test.imports, test.path)
-		if mi != test.mi {
-			t.Errorf("unexpected metaImport; got %v, want %v", mi, test.mi)
-		}
-
-		got := err
-		want := test.err
-		if (got == nil) != (want == nil) {
-			t.Errorf("unexpected error; got %v, want %v", got, want)
-		}
-	}
-}
