You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: heads.go
    path of file: ./repos/gitea/services/doctor
    
    the code of the file until where you have to start completion: // Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package doctor

import (
	"context"

	repo_model "code.gitea.io/gitea/models/repo"
	"code.gitea.io/gitea/modules/git"
	"code.gitea.io/gitea/modules/log"
)

func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) error {
	numRepos := 0
	numHeadsBroken := 0
	numDefaultBranchesBroken := 0
	numReposUpdated := 0
	err := iterateRepositories(ctx, func(repo *repo_model.Repository) error {
		numRepos++
		_, _, defaultBranchErr := git.NewCommand(ctx, "rev-parse").AddDashesAndList(repo.DefaultBranch).RunStdString(&git.RunOpts{Dir: repo.RepoPath()})

		head, _, headErr := git.NewCommand(ctx, "symbolic-ref", "--short", "HEAD").RunStdString(&git.RunOpts{Dir: repo.RepoPath()})

		// what we expect: default branch is valid, and HEAD points to it
		if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch {
			return nil
		}

		if headErr != nil {
			numHeadsBroken++
		}
		if defaultBranchErr != nil {
			numDefaultBranchesBroken++
		}

		// if default branch is broken, let the user fix that in the UI
		if defaultBranchErr != nil {
			logger.Warn("Default branch for %s/%s doesn't point to a valid commit", repo.OwnerName, repo.Name)
			return nil
		}

		// if we're not autofixing, that's all we can do
		if !autofix {
			return nil
		}

		// otherwise, let's try fixing HEAD
		err := git.NewCommand(ctx, "symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch).Run(&git.RunOpts{Dir: repo.RepoPath()})
		if err != nil {
			logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err)
			return nil
		}
		numReposUpdated++
		return nil
	})
	if err != nil {
		logger.Critical("Error when fixing repo HEADs: %v", err)
	}

	if autofix {
		logger.Info("Out of %d repos, HEADs for %d are now fixed and HEADS for %d are still broken
    
func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) error {
	numRepos := 0
	numHeadsBroken := 0
	numDefaultBranchesBroken := 0
	numReposUpdated := 0
	err := iterateRepositories(ctx, func(repo *repo_model.Repository) error {
		numRepos++
		_, _, defaultBranchErr := git.NewCommand(ctx, "rev-parse").AddDashesAndList(repo.DefaultBranch).RunStdString(&git.RunOpts{Dir: repo.RepoPath()})

		head, _, headErr := git.NewCommand(ctx, "symbolic-ref", "--short", "HEAD").RunStdString(&git.RunOpts{Dir: repo.RepoPath()})

		// what we expect: default branch is valid, and HEAD points to it
		if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch {
			return nil
		}

		if headErr != nil {
			numHeadsBroken++
		}
		if defaultBranchErr != nil {
			numDefaultBranchesBroken++
		}

		// if default branch is broken, let the user fix that in the UI
		if defaultBranchErr != nil {
			logger.Warn("Default branch for %s/%s doesn't point to a valid commit", repo.OwnerName, repo.Name)
			return nil
		}

		// if we're not autofixing, that's all we can do
		if !autofix {
			return nil
		}

		// otherwise, let's try fixing HEAD
		err := git.NewCommand(ctx, "symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch).Run(&git.RunOpts{Dir: repo.RepoPath()})
		if err != nil {
			logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err)
			return nil
		}
		numReposUpdated++
		return nil
	})
	if err != nil {
		logger.Critical("Error when fixing repo HEADs: %v", err)
	}

	if autofix {
		logger.Info("Out of %d repos, HEADs for %d are now fixed and HEADS for %d are still broken", numRepos, numReposUpdated, numDefaultBranchesBroken+numHeadsBroken-numReposUpdated)
	} else {
		if numHeadsBroken == 0 && numDefaultBranchesBroken == 0 {
			logger.Info("All %d repos have their HEADs in the correct state", numRepos)
		} else {
			if numHeadsBroken == 0 && numDefaultBranchesBroken != 0 {
				logger.Critical("Default branches are broken for %d/%d repos", numDefaultBranchesBroken, numRepos)
			} else if numHeadsBroken != 0 && numDefaultBranchesBroken == 0 {
				logger.Warn("HEADs are broken for %d/%d repos", numHeadsBroken, numRepos)
			} else {
				logger.Critical("Out of %d repos, HEADS are broken for %d and default branches are broken for %d", numRepos, numHeadsBroken, numDefaultBranchesBroken)
			}
		}
	}

	return err
}