func (ctx *Context) modifyFetch(pkg *Package, uncommitted, hasVersion bool, version string) error {
	vp := ctx.VendorFilePackagePath(pkg.Path)
	if vp == nil {
		vp = &vendorfile.Package{
			Add:  true,
			Path: pkg.Path,
		}
		ctx.VendorFile.Package = append(ctx.VendorFile.Package, vp)
	}
	if hasVersion {
		vp.Version = version
		pkg.Version = version
		pkg.HasVersion = true
	}
	if pkg.IncludeTree {
		vp.Tree = pkg.IncludeTree
	}
	pkg.Origin = strings.TrimPrefix(pkg.Origin, ctx.RootImportPath+"/"+ctx.VendorFolder+"/")
	vp.Origin = pkg.Origin
	origin := vp.Origin
	if len(vp.Origin) == 0 {
		origin = vp.Path
	}
	ps := &pkgspec.Pkg{
		Path:       pkg.Path,
		Origin:     origin,
		HasVersion: hasVersion,
		Version:    version,
	}
	dest := filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(pkg.Path))
	ctx.Operation = append(ctx.Operation, &Operation{
		Type: OpFetch,
		Pkg:  pkg,
		Src:  ps.String(),
		Dest: dest,
	})
	return nil
}
modify function to fetch given package.
package context
import (
	"bytes"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"math"
	"path"
	"path/filepath"
	"strings"
	"time"
	"github.com/kardianos/govendor/internal/pathos"
	os "github.com/kardianos/govendor/internal/vos"
	"github.com/kardianos/govendor/pkgspec"
	"github.com/kardianos/govendor/vcs"
	"github.com/kardianos/govendor/vendorfile"
	"github.com/pkg/errors"
)
type OperationState byte
const (
	OpReady  OperationState = iota  
	OpIgnore                        
	OpDone                          
)
type OperationType byte
const (
	OpCopy OperationType = iota
	OpRemove
	OpFetch
)
func (t OperationType) String() string {
	switch t {
	default:
		panic("unknown operation type")
	case OpCopy:
		return "copy"
	case OpRemove:
		return "remove"
	case OpFetch:
		return "fetch"
	}
}
type Operation struct {
	Type OperationType
	Pkg *Package
	Src string
	Dest string
	IgnoreFile []string
	State OperationState
	Uncommitted bool
}
type Conflict struct {
	Canonical string
	Local     string
	Operation []*Operation
	OpIndex   int
	Resolved  bool
}
type Modify byte
const (
	AddUpdate Modify = iota  
	Add                      
	Update                   
	Remove                   
	Fetch                    
)
type ModifyOption byte
const (
	Uncommitted ModifyOption = iota
	MatchTree
	IncludeTree
)
func (ctx *Context) ModifyStatus(sg StatusGroup, mod Modify, mops ...ModifyOption) error {
	if ctx.added == nil {
		ctx.added = make(map[string]bool, 10)
	}
	list, err := ctx.Status()
	if err != nil {
		return err
	}
statusLoop:
	for _, item := range list {
		if !item.Status.MatchGroup(sg) {
			continue
		}
		if ctx.added[item.Pkg.PathOrigin()] {
			continue
		}
		if item.Status.Presence == PresenceExcluded {
			continue
		}
		if mod == Add {
			if ctx.VendorFilePackagePath(item.Pkg.Path) != nil {
				continue
			}
			for _, pkg := range ctx.Package {
				if pkg.Status.Location == LocationVendor && item.Pkg.Path == pkg.Path {
					continue statusLoop
				}
			}
		}
		err = ctx.modify(item.Pkg, mod, mops)
		if err != nil {
			if _, is := err.(ErrTreeChildren); is {
				continue
			}
			if _, is := err.(ErrTreeParents); is {
				continue
			}
			return err
		}
	}
	return nil
}
func (ctx *Context) ModifyImport(imp *pkgspec.Pkg, mod Modify, mops ...ModifyOption) error {
	var err error
	if ctx.added == nil {
		ctx.added = make(map[string]bool, 10)
	}
	if len(imp.Origin) == 0 {
		for _, vpkg := range ctx.VendorFile.Package {
			if vpkg.Remove {
				continue
			}
			if vpkg.Path == imp.Path {
				imp.Origin = vpkg.Origin
			}
		}
	}
	if !imp.MatchTree {
		if !ctx.added[imp.PathOrigin()] {
			err = ctx.modify(imp, mod, mops)
			if err != nil {
				return err
			}
		}
		return nil
	}
	list, err := ctx.Status()
	if err != nil {
		return err
	}
	match := imp.Path + "/"
	for _, item := range list {
		if ctx.added[item.Pkg.PathOrigin()] {
			continue
		}
		if item.Pkg.Path != imp.Path && !strings.HasPrefix(item.Pkg.Path, match) {
			continue
		}
		if imp.HasVersion {
			item.Pkg.HasVersion = true
			item.Pkg.Version = imp.Version
		}
		item.Pkg.Origin = path.Join(imp.PathOrigin(), strings.TrimPrefix(item.Pkg.Path, imp.Path))
		err = ctx.modify(item.Pkg, mod, mops)
		if err != nil {
			return err
		}
	}
	return nil
}
func (ctx *Context) modify(ps *pkgspec.Pkg, mod Modify, mops []ModifyOption) error {
	ctx.added[ps.PathOrigin()] = true
	for _, mop := range mops {
		switch mop {
		default:
			panic("unknown case")
		case Uncommitted:
			ps.Uncommitted = true
		case MatchTree:
			ps.MatchTree = true
		case IncludeTree:
			ps.IncludeTree = true
		}
	}
	var err error
	if !ctx.loaded || ctx.dirty {
		err = ctx.loadPackage()
		if err != nil {
			return err
		}
	}
	tree := ps.IncludeTree
	switch mod {
	case Add, Update, AddUpdate:
		_, _, err = ctx.findImportDir("", ps.PathOrigin())
		if err != nil {
			return err
		}
	}
	var pkg *Package
	var foundPkg bool
	if !foundPkg {
		localPath := path.Join(ctx.RootImportPath, ctx.VendorFolder, ps.Path)
		pkg, foundPkg = ctx.Package[localPath]
		foundPkg = foundPkg && pkg.Status.Presence != PresenceMissing
	}
	if !foundPkg {
		pkg, foundPkg = ctx.Package[ps.Path]
		foundPkg = foundPkg && pkg.Status.Presence != PresenceMissing
	}
	if !foundPkg {
		pkg, foundPkg = ctx.Package[ps.PathOrigin()]
		foundPkg = foundPkg && pkg.Status.Presence != PresenceMissing
	}
	if !foundPkg {
		pkg, err = ctx.addSingleImport(ctx.RootDir, ps.PathOrigin(), tree)
		if err != nil {
			return err
		}
		if pkg == nil {
			return nil
		}
		pkg.Origin = ps.PathOrigin()
		pkg.Path = ps.Path
	}
	pkg.HasOrigin = ps.HasOrigin
	if ps.HasOrigin {
		pkg.Origin = ps.Origin
	}
	if tree && mod != Remove {
		pkg.IncludeTree = true
	}
	if mod != Remove {
		if pkg.IncludeTree {
			children := ctx.findPackageChild(pkg)
			if len(children) > 0 {
				return ErrTreeChildren{path: pkg.Path, children: children}
			}
		}
		treeParents := ctx.findPackageParentTree(pkg)
		if len(treeParents) > 0 {
			return ErrTreeParents{path: pkg.Path, parents: treeParents}
		}
	}
	localExists, err := hasGoFileInFolder(filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(ps.Path)))
	if err != nil {
		return err
	}
	if mod == Add && localExists {
		return ErrPackageExists{path.Join(ctx.RootImportPath, ctx.VendorFolder, ps.Path)}
	}
	dprintf("stage 2: begin!\n")
	switch mod {
	case Add:
		return ctx.modifyAdd(pkg, ps.Uncommitted)
	case AddUpdate:
		return ctx.modifyAdd(pkg, ps.Uncommitted)
	case Update:
		return ctx.modifyAdd(pkg, ps.Uncommitted)
	case Remove:
		return ctx.modifyRemove(pkg)
	case Fetch:
		return ctx.modifyFetch(pkg, ps.Uncommitted, ps.HasVersion, ps.Version)
	default:
		panic("mod switch: case not handled")
	}
}
func (ctx *Context) getIngoreFiles(src string) (ignoreFile, imports []string, err error) {
	srcDir, err := os.Open(src)
	if err != nil {
		return nil, nil, err
	}
	fl, err := srcDir.Readdir(-1)
	srcDir.Close()
	if err != nil {
		return nil, nil, err
	}
	importMap := make(map[string]struct{}, 12)
	imports = make([]string, 0, 12)
	for _, fi := range fl {
		if fi.IsDir() {
			continue
		}
		if fi.Name()[0] == '.' {
			continue
		}
		tags, fileImports, err := ctx.getFileTags(filepath.Join(src, fi.Name()), nil)
		if err != nil {
			return nil, nil, err
		}
		ignoreItem := false
		for _, tag := range tags {
			for _, ignore := range ctx.ignoreTag {
				if tag == ignore {
					ignoreItem = true
				}
			}
		}
		if ignoreItem {
			ignoreFile = append(ignoreFile, fi.Name())
		} else {
			for _, imp := range fileImports {
				importMap[imp] = struct{}{}
			}
		}
	}
	for imp := range importMap {
		imports = append(imports, imp)
	}
	return ignoreFile, imports, nil
}
func (ctx *Context) modifyAdd(pkg *Package, uncommitted bool) error {
	var err error
	src := pkg.OriginDir
	dprintf("found import: %q\n", src)
	var ignoreFile []string
	if cpkg, found := ctx.Package[pkg.Path]; found {
		ignoreFile = cpkg.ignoreFile
	} else {
		var err error
		ignoreFile, _, err = ctx.getIngoreFiles(src)
		if err != nil {
			return err
		}
	}
	dest := filepath.Join(ctx.RootDir, ctx.VendorFolder, pathos.SlashToFilepath(pkg.Path))
	if pathos.FileStringEquals(src, dest) {
		return nil
	}
	dprintf("add op: %q\n", src)
	vp := ctx.VendorFilePackagePath(pkg.Path)
	if vp == nil {
		vp = &vendorfile.Package{
			Add:  true,
			Path: pkg.Path,
		}
		ctx.VendorFile.Package = append(ctx.VendorFile.Package, vp)
	}
	if pkg.IncludeTree {
		vp.Tree = pkg.IncludeTree
	}
	if pkg.HasOrigin {
		vp.Origin = pkg.Origin
	}
	if pkg.Path != pkg.Local && pkg.inVendor && vp.Add {
		vp.Origin = pkg.Local
	}
	system, err := vcs.FindVcs(pkg.Gopath, src)
	if err != nil {
		return err
	}
	dirtyAndUncommitted := false
	if system != nil {
		if system.Dirty {
			if !uncommitted {
				return ErrDirtyPackage{pkg.Path}
			}
			dirtyAndUncommitted = true
			if len(vp.ChecksumSHA1) == 0 {
				vp.ChecksumSHA1 = "uncommitted/version="
			}
		} else {
			vp.Revision = system.Revision
			if system.RevisionTime != nil {
				vp.RevisionTime = system.RevisionTime.UTC().Format(time.RFC3339)
			}
		}
	}
	ctx.Operation = append(ctx.Operation, &Operation{
		Type:       OpCopy,
		Pkg:        pkg,
		Src:        src,
		Dest:       dest,
		IgnoreFile: ignoreFile,
		Uncommitted: dirtyAndUncommitted,
	})
	if !ctx.rewriteImports {
		return nil
	}
	mvSet := make(map[*Package]struct{}, 3)
	ctx.makeSet(pkg, mvSet)
	for r := range mvSet {
		to := path.Join(ctx.RootImportPath, ctx.VendorFolder, r.Path)
		dprintf("RULE: %s -> %s\n", r.Local, to)
		ctx.RewriteRule[r.Path] = to
		ctx.RewriteRule[r.Local] = to
	}
	return nil
}
func (ctx *Context) modifyRemove(pkg *Package) error {
	vp := ctx.VendorFilePackagePath(pkg.Path)
	if vp != nil {
		vp.Remove = true
	}
	if len(pkg.Dir) == 0 {
		return nil
	}
	if pathos.FileHasPrefix(pkg.Dir, ctx.RootDir) == false {
		return nil
	}
	if pkg.Status.Location == LocationLocal {
		return nil
	}
	ctx.Operation = append(ctx.Operation, &Operation{
		Type: OpRemove,
		Pkg:  pkg,
		Src:  pkg.Dir,
		Dest: "",
	})
	if !ctx.rewriteImports {
		return nil
	}
	mvSet := make(map[*Package]struct{}, 3)
	ctx.makeSet(pkg, mvSet)
	for r := range mvSet {
		dprintf("RULE: %s -> %s\n", r.Local, r.Path)
		ctx.RewriteRule[r.Local] = r.Path
	}
	return nil
}