func()

in cmd/publishing-bot/publisher.go [57:145]


func (p *PublisherMunger) updateSourceRepo() (map[string]plumbing.Hash, error) {
	repoDir := filepath.Join(p.baseRepoPath, p.config.SourceRepo)

	// fetch origin
	glog.Infof("Fetching origin at %s.", repoDir)
	r, err := gogit.PlainOpen(repoDir)
	if err != nil {
		return nil, fmt.Errorf("failed to open repo at %s: %v", repoDir, err)
	}
	if err := r.Fetch(&gogit.FetchOptions{
		Tags:     gogit.AllTags,
		Progress: os.Stdout,
	}); err != nil && err != gogit.NoErrAlreadyUpToDate {
		return nil, fmt.Errorf("failed to fetch at %s: %v", repoDir, err)
	}

	// disable text conversion
	// TODO: remove when go-git supports text conversion to be consistent with cli git
	attrFile := filepath.Join(repoDir, ".git", "info", "attributes")
	if _, err := os.Stat(attrFile); os.IsNotExist(err) {
		glog.Infof("Disabling text conversion at %s.", repoDir)
		err := os.MkdirAll(filepath.Join(repoDir, ".git", "info"), 0755)
		if err != nil {
			return nil, fmt.Errorf("creating .git/info: %v", err)
		}

		if err := ioutil.WriteFile(attrFile, []byte(`
* -text
`), 0644); err != nil {
			return nil, fmt.Errorf("failed to create .git/info/attributes: %v", err)
		}

		fis, err := ioutil.ReadDir(repoDir)
		if err != nil {
			return nil, err
		}
		for _, fi := range fis {
			if fi.Name() != ".git" {
				if err := os.RemoveAll(filepath.Join(repoDir, fi.Name())); err != nil {
					return nil, err
				}
			}
		}
	}

	// checkout head
	glog.Infof("Checking out HEAD at %s.", repoDir)
	w, err := r.Worktree()
	if err != nil {
		return nil, fmt.Errorf("failed to open worktree at %s: %v", repoDir, err)
	}
	head, err := r.Head()
	if err != nil {
		return nil, fmt.Errorf("failed to get head at %s: %v", repoDir, err)
	}
	if err := w.Checkout(&gogit.CheckoutOptions{Hash: head.Hash(), Force: true}); err != nil {
		return nil, fmt.Errorf("failed to checkout HEAD at %s: %v", repoDir, err)
	}

	// create/update local branch for all origin branches. Those are fetches into the destination repos later (as upstream/<branch>).
	refs, err := r.Storer.IterReferences()
	if err != nil {
		return nil, fmt.Errorf("failed to get branches: %v", err)
	}
	glog.Infof("Updating local branches at %s.", repoDir)
	heads := map[string]plumbing.Hash{}
	if err = refs.ForEach(func(ref *plumbing.Reference) error {
		name := ref.Name().String()

		originPrefix := "refs/remotes/origin/"
		if !strings.Contains(name, originPrefix) || ref.Type() != plumbing.HashReference {
			return nil
		}

		shortName := strings.TrimPrefix(name, originPrefix)
		localBranch := plumbing.NewHashReference(plumbing.ReferenceName("refs/heads/"+shortName), ref.Hash())
		if err := r.Storer.SetReference(localBranch); err != nil {
			return fmt.Errorf("failed to create reference %s pointing to %s", localBranch.Name(), localBranch.Hash().String())
		}

		heads[shortName] = localBranch.Hash()

		return nil
	}); err != nil {
		return nil, fmt.Errorf("failed to process branches: %v", err)
	}

	return heads, nil
}