// Copyright 2017 The Fuchsia 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 project

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"strings"

	"go.fuchsia.dev/jiri"
	"go.fuchsia.dev/jiri/gitutil"
)

type importCache struct {
	localManifest bool
	ref           string

	// keeps track of first import tag, this is used to give helpful error
	// message in the case of import conflict
	parentImport string
}

type loader struct {
	Projects         Projects
	ProjectOverrides map[string]Project
	ImportOverrides  map[string]Import
	ProjectLocks     ProjectLocks
	Hooks            Hooks
	Packages         Packages
	PackageLocks     PackageLocks
	TmpDir           string
	localProjects    Projects
	importProjects   Projects
	importCacheMap   map[string]importCache
	importTree       importTree
	update           bool
	cycleStack       []cycleInfo
	manifests        map[string]bool
	lockfiles        map[string]bool
	parentFile       string
}

type importTreeNode struct {
	parents            map[*importTreeNode]bool
	children           map[*importTreeNode]bool
	tag                string
	computedAttributes attributes
}

type importTree struct {
	root          *importTreeNode
	pool          map[string]*importTreeNode
	filenameMap   map[string]bool
	projectKeyMap map[ProjectKey]*importTreeNode
}

func newImportTree() importTree {
	return importTree{
		root: &importTreeNode{
			make(map[*importTreeNode]bool),
			make(map[*importTreeNode]bool),
			"",
			nil,
		},
		pool:          make(map[string]*importTreeNode),
		filenameMap:   make(map[string]bool),
		projectKeyMap: make(map[ProjectKey]*importTreeNode),
	}
}

func (t *importTree) getNode(repoPath, file, ref string) *importTreeNode {
	key := filepath.Join(repoPath, file) + ":" + ref
	if v, ok := t.pool[key]; ok {
		return v
	}
	v := &importTreeNode{
		make(map[*importTreeNode]bool),
		make(map[*importTreeNode]bool),
		key,
		nil,
	}
	if len(t.pool) == 0 {
		t.root.addChild(v)
	}
	t.pool[key] = v
	return v
}

func (t *importTree) buildImportAttributes() {
	// Due to the logic in how remote imports are handled, the
	// manifest loader will create two nodes for a single remote import,
	// causing second one as an orphan. A simple solution is just
	// connect the orphan nodes to the Root to build a connected tree.
	for _, v := range t.pool {
		if len(v.parents) == 0 {
			t.root.addChild(v)
		}
	}
	// The file name of a manifest is used as a git attributes name only if that
	// file name is unique.
	dupMap := make(map[string]bool)
	for k := range t.filenameMap {
		filename := filepath.Base(k)
		if _, ok := dupMap[filename]; ok {
			dupMap[filename] = true
		} else {
			dupMap[filename] = false
		}
	}
	dfsAddAttribute(t.root, newAttributes(""))
	for _, node := range t.pool {
		for attr := range node.computedAttributes {
			if v, ok := dupMap[attr]; ok && v {
				delete(node.computedAttributes, attr)
			}
		}
	}
}

func dfsAddAttribute(curNode *importTreeNode, parentAttrs attributes) {
	if curNode.computedAttributes == nil {
		curNode.computedAttributes = newAttributes(curNode.tag)
	}
	curNode.computedAttributes.Add(parentAttrs)
	for k := range curNode.children {
		dfsAddAttribute(k, curNode.computedAttributes)
	}
}

// (TODO:haowei) generateAttributeGraph generate a graphviz .dot file of
// importTree for debugging purpose. It should be removed once .gitattribute
// generator is considered as stable.
func (t *importTree) generateAttributeGraph() string {
	var buf bytes.Buffer
	buf.WriteString("\ndigraph G {\n")
	nodeCount := 1
	nameMap := make(map[*importTreeNode]string)
	nameMap[t.root] = "n0"
	for _, v := range t.pool {
		nameMap[v] = fmt.Sprintf("n%d", nodeCount)
		nodeCount++
	}

	// The file name of a manifest is used as a git attributes name only if that
	// file name is unique.
	dupMap := make(map[string]bool)
	for k := range t.filenameMap {
		filename := filepath.Base(k)
		if _, ok := dupMap[filename]; ok {
			dupMap[filename] = true
		} else {
			dupMap[filename] = false
		}
	}
	// Output nodes
	for k, v := range nameMap {
		attrs := newAttributes(k.tag)
		for attr := range attrs {
			if v, ok := dupMap[attr]; ok && v {
				delete(attrs, attr)
			}
		}
		buf.WriteString(fmt.Sprintf("\t%s[label=\"%s,%p\"];\n", v, attrs.String(), k))
	}
	buf.WriteString("\n")
	// Output edges
	for k := range nameMap {
		for child := range k.children {
			nameSource := nameMap[k]
			nameTarget, ok := nameMap[child]
			if !ok {
				fmt.Printf("ERROR: cound not find target node %q,%p in nameMap\n", child.tag, child)
				continue
			}
			buf.WriteString(fmt.Sprintf("\t%s -> %s;\n", nameSource, nameTarget))
		}
	}

	buf.WriteString("\n}")
	return buf.String()
}

func (n *importTreeNode) addChild(other *importTreeNode) {
	if other == nil {
		return
	}
	n.children[other] = true
	other.parents[n] = true
}

func (ld *loader) cleanup() {
	if ld.TmpDir != "" {
		os.RemoveAll(ld.TmpDir)
		ld.TmpDir = ""
	}
}

type cycleInfo struct {
	file, key string
}

// newManifestLoader returns a new manifest loader.  The localProjects are used
// to resolve remote imports; if nil, encountering any remote import will result
// in an error.  If update is true, remote manifest import projects that don't
// exist locally are cloned under TmpDir, and inserted into localProjects.
//
// If update is true, remote changes to manifest projects will be fetched, and
// manifest projects that don't exist locally will be created in temporary
// directories, and added to localProjects.
func newManifestLoader(localProjects Projects, update bool, file string) *loader {
	return &loader{
		Projects:         make(Projects),
		ProjectOverrides: make(map[string]Project),
		ImportOverrides:  make(map[string]Import),
		ProjectLocks:     make(ProjectLocks),
		Hooks:            make(Hooks),
		Packages:         make(Packages),
		PackageLocks:     make(PackageLocks),
		localProjects:    localProjects,
		importProjects:   make(Projects),
		update:           update,
		importCacheMap:   make(map[string]importCache),
		manifests:        make(map[string]bool),
		lockfiles:        make(map[string]bool),
		importTree:       newImportTree(),
		parentFile:       file,
	}
}

// loadNoCycles checks for cycles in imports.  There are two types of cycles:
//   file - Cycle in the paths of manifest files in the local filesystem.
//   key  - Cycle in the remote manifests specified by remote imports.
//
// Example of file cycles.  File A imports file B, and vice versa.
//     file=manifest/A              file=manifest/B
//     <manifest>                   <manifest>
//       <localimport file="B"/>      <localimport file="A"/>
//     </manifest>                  </manifest>
//
// Example of key cycles.  The key consists of "remote/manifest", e.g.
//   https://vanadium.googlesource.com/manifest/v2/default
// In the example, key x/A imports y/B, and vice versa.
//     key=x/A                               key=y/B
//     <manifest>                            <manifest>
//       <import remote="y" manifest="B"/>     <import remote="x" manifest="A"/>
//     </manifest>                           </manifest>
//
// The above examples are simple, but the general strategy is demonstrated.  We
// keep a single stack for both files and keys, and push onto each stack before
// running the recursive read or update function, and pop the stack when the
// function is done.  If we see a duplicate on the stack at any point, we know
// there's a cycle.  Note that we know the file for both local and remote
// imports, but we only know the key for remote imports; the key for local
// imports is empty.
//
// A more complex case would involve a combination of local and remote imports,
// using the "root" attribute to change paths on the local filesystem.  In this
// case the key will eventually expose the cycle.
func (ld *loader) loadNoCycles(jirix *jiri.X, root, repoPath, file, ref, cycleKey, parentImport string, localManifest bool) error {
	f := file
	if repoPath != "" {
		f = filepath.Join(repoPath, file)
	}
	info := cycleInfo{f, cycleKey}
	for _, c := range ld.cycleStack {
		switch {
		case f == c.file:
			return fmt.Errorf("import cycle detected in local manifest files: %q", append(ld.cycleStack, info))
		case cycleKey == c.key && cycleKey != "":
			return fmt.Errorf("import cycle detected in remote manifest imports: %q", append(ld.cycleStack, info))
		}
	}
	ld.cycleStack = append(ld.cycleStack, info)
	if err := ld.load(jirix, root, repoPath, file, ref, parentImport, localManifest); err != nil {
		return err
	}
	ld.cycleStack = ld.cycleStack[:len(ld.cycleStack)-1]
	return nil
}

// shortFileName returns the relative path if file is relative to root,
// otherwise returns the file name unchanged.
func shortFileName(root, repoPath, file, ref string) string {
	if repoPath != "" {
		return fmt.Sprintf("%s %s:%s", shortFileName(root, "", repoPath, ""), ref, file)
	}
	if p := root + string(filepath.Separator); strings.HasPrefix(file, p) {
		return file[len(p):]
	}
	return file
}

func (ld *loader) Load(jirix *jiri.X, root, repoPath, file, ref, cycleKey, parentImport string, localManifest bool) error {
	jirix.TimerPush("load " + shortFileName(jirix.Root, repoPath, file, ref))
	defer jirix.TimerPop()
	return ld.loadNoCycles(jirix, root, repoPath, file, ref, cycleKey, parentImport, localManifest)
}

func (ld *loader) cloneManifestRepo(jirix *jiri.X, remote *Import, cacheDirPath string, localManifest bool) error {
	if !ld.update || localManifest {
		jirix.Logger.Warningf("import %q not found locally, getting from server. Please check your manifest file (default: .jiri_manifest).\nMake sure that the 'name' attributes on the 'import' and 'project' tags match and that there is a corresponding 'project' tag for every 'import' tag.\n\n", remote.Name)
	}
	jirix.Logger.Debugf("clone manifest project %q", remote.Name)
	// The remote manifest project doesn't exist locally.  Clone it into a
	// temp directory, and add it to ld.localProjects.
	if ld.TmpDir == "" {
		var err error
		if ld.TmpDir, err = ioutil.TempDir("", "jiri-load"); err != nil {
			return fmt.Errorf("TempDir() failed: %v", err)
		}
	}
	path := filepath.Join(ld.TmpDir, remote.projectKeyFileName())
	p, err := remote.toProject(path)
	if err != nil {
		return err
	}
	if err := os.MkdirAll(path, 0755); err != nil {
		return fmtError(err)
	}
	remoteUrl := rewriteRemote(jirix, p.Remote)
	task := jirix.Logger.AddTaskMsg("Creating manifest: %s", remote.Name)
	defer task.Done()
	if cacheDirPath != "" {
		logStr := fmt.Sprintf("update/create cache for project %q", remote.Name)
		jirix.Logger.Debugf(logStr)
		task := jirix.Logger.AddTaskMsg(logStr)
		defer task.Done()
		if err := updateOrCreateCache(jirix, cacheDirPath, remoteUrl, remote.RemoteBranch, remote.Revision, 0); err != nil {
			return err
		}
	}
	opts := []gitutil.CloneOpt{gitutil.ReferenceOpt(cacheDirPath), gitutil.NoCheckoutOpt(true)}
	if jirix.UsePartialClone(p.Remote) {
		opts = append(opts, gitutil.OmitBlobsOpt(true))
	}
	if jirix.OffloadPackfiles {
		opts = append(opts, gitutil.OffloadPackfilesOpt(true))
	}
	if err := clone(jirix, remoteUrl, path, opts...); err != nil {
		return err
	}
	scm := gitutil.New(jirix, gitutil.RootDirOpt(p.Path))
	if jirix.OffloadPackfiles {
		if err := scm.Config("fetch.uriprotocols", "https"); err != nil {
			return err
		}
	}
	if jirix.UsePartialClone(p.Remote) && cacheDirPath != "" {
		// Set Cache Remote
		if err := scm.Config("extensions.partialClone", "origin"); err != nil {
			return err
		}
		if err := scm.AddOrReplacePartialRemote("cache", cacheDirPath); err != nil {
			return err
		}
	}

	p.Revision = remote.Revision
	p.RemoteBranch = remote.RemoteBranch
	if err := checkoutHeadRevision(jirix, p, false); err != nil {
		return fmt.Errorf("Not able to checkout head for %s(%s): %v", p.Name, p.Path, err)
	}
	ld.localProjects[remote.ProjectKey()] = p
	return nil
}

// loadLockFile will recursively load lockfiles from dir to its parent directories until it
// reaches $JIRI_ROOT. It will only report errors on lockfiles such as unknown format or confliting data.
// All I/O related errors will be ignored.
func (ld *loader) loadLockFile(jirix *jiri.X, repoPath, dir, lockFileName, ref string) error {
	lockfile := filepath.Join(dir, lockFileName)
	lockKey := lockfile
	if repoPath != "" {
		lockKey = filepath.Join(repoPath, lockfile) + ":" + ref
	}
	if ld.lockfiles[lockKey] {
		return nil
	}

	if !(dir == "" || dir == "." || dir == jirix.Root || dir == string(filepath.Separator)) {
		if err := ld.loadLockFile(jirix, repoPath, filepath.Dir(dir), lockFileName, ref); err != nil {
			return err
		}
	}

	var data []byte
	if repoPath != "" {
		s, err := gitutil.New(jirix, gitutil.RootDirOpt(repoPath)).Show(ref, lockfile)
		if err != nil {
			// It's fine if jiri.lock cannot be find, skip this jiri.lock
			jirix.Logger.Debugf("Could not find %q in repository %q for ref %q", lockfile, repoPath, ref)
			return nil
		}
		data = []byte(s)
	} else {
		if _, err := os.Stat(lockfile); err != nil {
			if os.IsNotExist(err) {
				jirix.Logger.Debugf("could not find %q file at %q", lockFileName, lockfile)
			} else {
				jirix.Logger.Debugf("could not access %q file at %q due to error %v", lockFileName, lockfile, err)
			}
			return nil
		}
		temp, err := ioutil.ReadFile(lockfile)
		if err != nil {
			// Supress I/O errors as it is OK if a lockfile cannot be accessed.
			return nil
		}
		data = temp
	}
	if err := ld.parseLockData(jirix, data); err != nil {
		return err
	}
	if repoPath == "" {
		jirix.Logger.Debugf("loaded lockfile at %s", lockfile)
	} else {
		jirix.Logger.Debugf("loaded lockfile at %q in repository %q for ref %q", lockfile, repoPath, ref)
	}
	ld.lockfiles[lockKey] = true
	return nil
}

func (ld *loader) parseLockData(jirix *jiri.X, data []byte) error {
	projectLocks, pkgLocks, err := UnmarshalLockEntries(data)
	if err != nil {
		return err
	}

	for k, v := range projectLocks {
		if projLock, ok := ld.ProjectLocks[k]; ok {
			if projLock != v && !jirix.UsingImportOverride {
				return fmt.Errorf("conflicting project lock entries %+v with %+v", projLock, v)
			}
		} else {
			ld.ProjectLocks[k] = v
		}
	}

	for k, v := range pkgLocks {
		if pkgLock, ok := ld.PackageLocks[k]; ok {
			// Only package locks may conflict during a normal 'jiri resolve'.
			// Treating conflicts as errors in all other scenarios.
			if !pkgLock.LockEqual(v) && !jirix.IgnoreLockConflicts && !jirix.UsingImportOverride {
				return fmt.Errorf("conflicting package lock entries %+v with %+v", pkgLock, v)
			}
		} else {
			ld.PackageLocks[k] = v
		}
	}

	return nil
}

func (ld *loader) load(jirix *jiri.X, root, repoPath, file, ref, parentImport string, localManifest bool) error {
	f := file
	if repoPath != "" {
		f = filepath.Join(repoPath, file)
	}
	if ld.manifests[f] {
		return nil
	}
	ld.manifests[f] = true

	loadManifestAndLocks := func(jirix *jiri.X, file string) (*Manifest, error) {
		if repoPath == "" {
			m, err := ManifestFromFile(jirix, file)
			if err != nil {
				return nil, fmt.Errorf("Error reading from manifest file %s %s:%s:error(%s)", repoPath, ref, file, err)
			}
			if jirix.LockfileEnabled {
				if err := ld.loadLockFile(jirix, repoPath, filepath.Dir(file), jirix.LockfileName, ref); err != nil {
					return nil, err
				}
			}
			return m, err
		}
		// repoPath != ""
		s, err := gitutil.New(jirix, gitutil.RootDirOpt(repoPath)).Show(ref, file)
		if err != nil {
			return nil, fmt.Errorf("Unable to get manifest file for %s %s:%s:error(%s)", repoPath, ref, file, err)
		}
		m, err := ManifestFromBytes([]byte(s))
		if err != nil {
			return nil, fmt.Errorf("Error reading from manifest file %s %s:%s:error(%s)", repoPath, ref, file, err)
		}
		if jirix.LockfileEnabled {
			if err := ld.loadLockFile(jirix, repoPath, filepath.Dir(file), jirix.LockfileName, ref); err != nil {
				return nil, err
			}
		}
		return m, nil
	}

	m, err := loadManifestAndLocks(jirix, file)
	if err != nil {
		return err
	}

	if jirix.UsingSnapshot && !jirix.OverrideOptional {
		// using attributes defined in snapshot file instead of
		// using predefined ones in jiri init.
		jirix.FetchingAttrs = m.Attributes
	}

	// Add override information
	if parentImport == "" {
		for _, p := range m.ProjectOverrides {
			// Reuse the MakeProjectKey function in case it is changed
			// in the future.
			key := string(p.Key())
			ld.ProjectOverrides[key] = p
		}
		for _, p := range m.ImportOverrides {
			// Reuse the MakeProjectKey function in case it is changed
			// in the future.
			key := string(p.ProjectKey())
			if !jirix.UsingImportOverride {
				jirix.UsingImportOverride = true
			}
			ld.ImportOverrides[key] = p
		}
	} else if len(m.ProjectOverrides)+len(m.ImportOverrides) > 0 {
		return fmt.Errorf("manifest %q contains overrides but was imported by %q. Overrides are allowed only in the root manifest", shortFileName(jirix.Root, repoPath, file, ref), parentImport)
	}

	// Use manifest's directory name and file name as default
	// git attributes. It will be later expanded using the
	// import relationships.
	defaultGitAttrs := func() string {
		manifestFile := file
		if repoPath != "" {
			manifestFile = filepath.Join(repoPath, manifestFile)
		}
		containingDir := filepath.Base(filepath.Dir(manifestFile))
		filename := file
		ld.importTree.filenameMap[filename] = false
		return containingDir + "," + filepath.Base(file)
	}
	self := ld.importTree.getNode(repoPath, file, ref)
	self.tag = defaultGitAttrs()
	// Process remote imports.
	for _, remote := range m.Imports {
		// Apply override if it exists.
		remote, err := overrideImport(jirix, remote, ld.ProjectOverrides, ld.ImportOverrides)
		if err != nil {
			return err
		}
		nextRoot := filepath.Join(root, remote.Root)
		remote.Name = filepath.Join(nextRoot, remote.Name)
		key := remote.ProjectKey()
		p, ok := ld.localProjects[key]
		cacheDirPath, err := cacheDirPathFromRemote(jirix, remote.Remote)
		if err != nil {
			return err
		}

		if !ok {
			if err := ld.cloneManifestRepo(jirix, &remote, cacheDirPath, localManifest); err != nil {
				return err
			}
			p = ld.localProjects[key]
		}
		// Reset the project to its specified branch and load the next file.  Note
		// that we call load() recursively, so multiple files may be loaded by
		// loadImport.
		p.Revision = remote.Revision
		p.RemoteBranch = remote.RemoteBranch
		ld.importProjects[key] = p
		pi := parentImport
		if pi == "" {
			pi = fmt.Sprintf("import[manifest=%q, remote=%q]", remote.Manifest, remote.Remote)
		}

		self.addChild(ld.importTree.getNode(repoPath, remote.Manifest, ""))
		if err := ld.loadImport(jirix, nextRoot, remote.Manifest, remote.cycleKey(), cacheDirPath, pi, p, localManifest); err != nil {
			return err
		}
	}

	// Process local imports.
	for _, local := range m.LocalImports {
		nextFile := filepath.Join(filepath.Dir(file), local.File)
		self.addChild(ld.importTree.getNode(repoPath, nextFile, ref))
		if err := ld.Load(jirix, root, repoPath, nextFile, ref, "", parentImport, localManifest); err != nil {
			return err
		}
	}

	hookMap := make(map[string][]*Hook)

	for idx := range m.Hooks {
		hook := &m.Hooks[idx]
		if err := hook.validate(); err != nil {
			return err
		}
		hookMap[hook.ProjectName] = append(hookMap[hook.ProjectName], hook)
	}

	// Collect projects.
	for _, project := range m.Projects {
		// Apply override if it exists.
		project, err := overrideProject(jirix, project, ld.ProjectOverrides, ld.ImportOverrides)
		if err != nil {
			return err
		}
		// normalize project attributes
		project.ComputedAttributes = newAttributes(project.Attributes)
		project.Attributes = project.ComputedAttributes.String()
		// Make paths absolute by prepending <root>.
		project.absolutizePaths(filepath.Join(jirix.Root, root))

		if hooks, ok := hookMap[project.Name]; ok {
			for _, hook := range hooks {
				hook.ActionPath = project.Path
			}
		}

		// Prepend the root to the project name.  This will be a noop if the import is not rooted.
		project.Name = filepath.Join(root, project.Name)
		key := project.Key()

		if r, ok := ld.importProjects[key]; ok {
			// update revision for this project
			if r.Revision != "" && r.Revision != "HEAD" {
				if project.Revision == "" || project.Revision == "HEAD" {
					project.Revision = r.Revision
				} else if r.Revision != project.Revision {
					return fmt.Errorf("project %q found in %q defines different revision than its corresponding import tag.", key, shortFileName(jirix.Root, repoPath, file, ref))
				}
			}
		}

		if dup, ok := ld.Projects[key]; ok && !reflect.DeepEqual(dup, project) {
			// TODO(toddw): Tell the user the other conflicting file.
			return fmt.Errorf("duplicate project %q found in %q", key, shortFileName(jirix.Root, repoPath, file, ref))
		}

		// Record manifest location.
		project.ManifestPath = f

		// Associate project with importTreeNode for git attributes propagation.
		ld.importTree.projectKeyMap[key] = self

		ld.Projects[key] = project
	}

	for _, hook := range m.Hooks {
		if hook.ActionPath == "" {
			return fmt.Errorf("invalid hook %q for project %q. Please make sure you are importing project %q and this hook is in the manifest which directly/indirectly imports that project.", hook.Name, hook.ProjectName, hook.ProjectName)
		}
		key := hook.Key()
		ld.Hooks[key] = hook
	}

	for _, pkg := range m.Packages {
		// normalize package attributes.
		pkg.ComputedAttributes = newAttributes(pkg.Attributes)
		pkg.Attributes = pkg.ComputedAttributes.String()
		// Record manifest location.
		pkg.ManifestPath = f
		key := pkg.Key()
		ld.Packages[key] = pkg
	}
	return nil
}

func (ld *loader) loadImport(jirix *jiri.X, root, file, cycleKey, cacheDirPath, parentImport string, project Project, localManifest bool) (e error) {
	lm := localManifest
	ref := ""

	if v, ok := ld.importCacheMap[strings.Trim(project.Remote, "/")]; ok {
		// local manifest in cache takes precedence as this might be manifest mentioned in .jiri_manifest
		lm = v.localManifest
		ref = v.ref
		// check conflicting imports
		if !lm && ref != "JIRI_HEAD" {
			if tref, err := GetHeadRevision(jirix, project); err != nil {
				return err
			} else if tref != ref {
				return fmt.Errorf("Conflicting ref for import %s - %q and %q. There are conflicting imports in file:\n%s:\n'%s' and '%s'",
					jirix.Color.Red(project.Remote), ref, tref, jirix.Color.Yellow(ld.parentFile),
					jirix.Color.Yellow(v.parentImport), jirix.Color.Yellow(parentImport))
			}
		}
	} else {
		// We don't need to fetch or find ref for local manifest changes
		if !lm {
			// We only fetch on updates.
			if ld.update {
				// Fetch only if project not pinned or revision not available in
				// local git as we anyways update all the projects later.
				fetch := true
				if project.Revision != "" && project.Revision != "HEAD" {
					if _, err := gitutil.New(jirix, gitutil.RootDirOpt(project.Path)).Show(project.Revision, ""); err == nil {
						fetch = false
					}
				}
				if fetch {
					if cacheDirPath != "" {
						remoteUrl := rewriteRemote(jirix, project.Remote)
						if err := updateOrCreateCache(jirix, cacheDirPath, remoteUrl, project.RemoteBranch, project.Revision, 0); err != nil {
							return err
						}
					}
					if err := fetchAll(jirix, project); err != nil {
						return fmt.Errorf("Fetch failed for project(%s), %s", project.Path, err)
					}
				}
			} else {
				// If not updating then try to get file from JIRI_HEAD
				if _, err := gitutil.New(jirix, gitutil.RootDirOpt(project.Path)).Show("JIRI_HEAD", ""); err == nil {
					// JIRI_HEAD available, set ref
					ref = "JIRI_HEAD"
				}
			}
			if ref == "" {
				var err error
				if ref, err = GetHeadRevision(jirix, project); err != nil {
					return err
				}
			}
		}
		ld.importCacheMap[strings.Trim(project.Remote, "/")] = importCache{
			localManifest: lm,
			ref:           ref,
			parentImport:  parentImport,
		}
	}
	if lm {
		// load from local checked out file
		return ld.Load(jirix, root, "", filepath.Join(project.Path, file), "", cycleKey, parentImport, false)
	}
	return ld.Load(jirix, root, project.Path, file, ref, cycleKey, parentImport, false)
}

func (ld *loader) GenerateGitAttributesForProjects(jirix *jiri.X) {
	ld.importTree.buildImportAttributes()
	for k, v := range ld.Projects {
		if treeNode, ok := ld.importTree.projectKeyMap[k]; ok {
			v.GitAttributes = treeNode.computedAttributes.String()
			ld.Projects[k] = v
		}
	}
	jirix.Logger.Debugf("Generated dot file: %s", ld.importTree.generateAttributeGraph())
}
