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
}