func getGit()

in cmd/hub/git/pull.go [103:208]


func getGit(source manifest.Git, baseDir string, relDir string, componentName string, reset, optimizeGitRemotes, asSubtree bool,
	components []string, repos []LocalGitRepo) ([]string, []LocalGitRepo, error) {

	if source.Remote == "" || util.Contains(components, componentName) {
		return components, repos, nil
	}

	if source.LocalDir != "" {
		relDir = source.LocalDir
	}

	dir := relDir
	if !filepath.IsAbs(relDir) {
		relDir = filepath.Join(baseDir, relDir)
		var err error
		dir, err = filepath.Abs(relDir)
		if err != nil {
			return components, repos,
				fmt.Errorf("Error determining absolute path to pull into %s: %v", relDir, err)
		}
	}
	if config.Debug {
		log.Printf("Component `%s` Git repo dir is `%s`", componentName, dir)
	}
	if dirInRepoList(dir, repos) {
		return components, repos,
			fmt.Errorf("Directory %s used twice to pull Git repo", dir)
	}

	clone, err := emptyDir(dir, !asSubtree)
	if err != nil {
		return components, repos, err
	}

	remote := source.Remote
	remoteVerbose := fmt.Sprintf("`%s`", source.Remote)
	if optimizeGitRemotes && maybeRemote(remote) {
		remote = findLocalClone(repos, source.Remote, source.Ref)
		if remote != source.Remote {
			remoteVerbose = fmt.Sprintf("`%s` (%s)", remote, source.Remote)
			if config.Debug {
				log.Printf("Optimized component `%s` origin from `%s` to `%s`", componentName, source.Remote, remote)
			}
		}
	}

	if clone {
		if config.Verbose {
			log.Printf("Cloning from %s", remoteVerbose)
		}
		if asSubtree {
			return components, repos, errors.New("not implemented")
		} else {
			err = Clone(remote, source.Ref, dir)
			if err != nil {
				return components, repos, err
			}
		}
	} else {
		if config.Verbose {
			log.Printf("Updating from %s", remoteVerbose)
		}
		if asSubtree {
			// ensure remote with name = remote-<component name>
			// fetch source.Ref as _remote-<component name>/<Ref> remote branch
			// remember current branch
			// checkout _remote-<component name>/<Ref> as _remote-<component name>-<Ref>
			// split source.SubDir into _split-<component name>
			// pop to current branch
			// subtree merge into `dir` from _split-<component name>
			// delete _split-<component name>
			// delete _remote-<component name>-<Ref>
			// in case of error - show error, then note user to:
			// - return to current branch
			// - delete _split and _remote branches
			return components, repos, errors.New("not implemented")
		} else {
			if reset {
				// TODO: same way as git stash --include-untracked
				return components, repos, errors.New("not implemented")
			}

			err = Pull(source.Ref, dir)
			if err != nil {
				return components, repos,
					fmt.Errorf("Unable to pull Git repo %s into `%s`: %v", remoteVerbose, dir, err)
			}
		}
	}

	headName, _, err := HeadInfo(dir)
	if err != nil {
		util.Warn("%v", err)
	}

	return append(components, componentName),
		append(repos, LocalGitRepo{
			Remote:          source.Remote,
			OptimizedRemote: remote,
			Ref:             source.Ref,
			HeadRef:         headName,
			SubDir:          source.SubDir,
			AbsDir:          dir,
		}),
		nil
}