github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/git/repo_branch_gogit.go (about)

     1  // Copyright 2023 The GitBundle Inc. All rights reserved.
     2  // Copyright 2017 The Gitea Authors. All rights reserved.
     3  // Use of this source code is governed by a MIT-style
     4  // license that can be found in the LICENSE file.
     5  
     6  //go:build gogit
     7  
     8  package git
     9  
    10  import (
    11  	"context"
    12  	"strings"
    13  
    14  	"github.com/go-git/go-git/v5/plumbing"
    15  	"github.com/go-git/go-git/v5/plumbing/storer"
    16  )
    17  
    18  // IsObjectExist returns true if given reference exists in the repository.
    19  func (repo *Repository) IsObjectExist(name string) bool {
    20  	if name == "" {
    21  		return false
    22  	}
    23  
    24  	_, err := repo.gogitRepo.ResolveRevision(plumbing.Revision(name))
    25  
    26  	return err == nil
    27  }
    28  
    29  // IsReferenceExist returns true if given reference exists in the repository.
    30  func (repo *Repository) IsReferenceExist(name string) bool {
    31  	if name == "" {
    32  		return false
    33  	}
    34  
    35  	reference, err := repo.gogitRepo.Reference(plumbing.ReferenceName(name), true)
    36  	if err != nil {
    37  		return false
    38  	}
    39  	return reference.Type() != plumbing.InvalidReference
    40  }
    41  
    42  // IsBranchExist returns true if given branch exists in current repository.
    43  func (repo *Repository) IsBranchExist(name string) bool {
    44  	if name == "" {
    45  		return false
    46  	}
    47  	reference, err := repo.gogitRepo.Reference(plumbing.ReferenceName(BranchPrefix+name), true)
    48  	if err != nil {
    49  		return false
    50  	}
    51  	return reference.Type() != plumbing.InvalidReference
    52  }
    53  
    54  // GetBranches returns branches from the repository, skipping skip initial branches and
    55  // returning at most limit branches, or all branches if limit is 0.
    56  func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
    57  	var branchNames []string
    58  
    59  	branches, err := repo.gogitRepo.Branches()
    60  	if err != nil {
    61  		return nil, 0, err
    62  	}
    63  
    64  	i := 0
    65  	count := 0
    66  	_ = branches.ForEach(func(branch *plumbing.Reference) error {
    67  		count++
    68  		if i < skip {
    69  			i++
    70  			return nil
    71  		} else if limit != 0 && count > skip+limit {
    72  			return nil
    73  		}
    74  
    75  		branchNames = append(branchNames, strings.TrimPrefix(branch.Name().String(), BranchPrefix))
    76  		return nil
    77  	})
    78  
    79  	// TODO: Sort?
    80  
    81  	return branchNames, count, nil
    82  }
    83  
    84  // WalkReferences walks all the references from the repository
    85  // refType should be empty, ObjectTag or ObjectBranch. All other values are equivalent to empty.
    86  func WalkReferences(ctx context.Context, repoPath string, walkfn func(sha1, refname string) error) (int, error) {
    87  	repo := RepositoryFromContext(ctx, repoPath)
    88  	if repo == nil {
    89  		var err error
    90  		repo, err = OpenRepository(ctx, repoPath)
    91  		if err != nil {
    92  			return 0, err
    93  		}
    94  		defer repo.Close()
    95  	}
    96  
    97  	i := 0
    98  	iter, err := repo.gogitRepo.References()
    99  	if err != nil {
   100  		return i, err
   101  	}
   102  	defer iter.Close()
   103  
   104  	err = iter.ForEach(func(ref *plumbing.Reference) error {
   105  		err := walkfn(ref.Hash().String(), string(ref.Name()))
   106  		i++
   107  		return err
   108  	})
   109  	return i, err
   110  }
   111  
   112  // WalkReferences walks all the references from the repository
   113  func (repo *Repository) WalkReferences(arg ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) {
   114  	i := 0
   115  	var iter storer.ReferenceIter
   116  	var err error
   117  	switch arg {
   118  	case ObjectTag:
   119  		iter, err = repo.gogitRepo.Tags()
   120  	case ObjectBranch:
   121  		iter, err = repo.gogitRepo.Branches()
   122  	default:
   123  		iter, err = repo.gogitRepo.References()
   124  	}
   125  	if err != nil {
   126  		return i, err
   127  	}
   128  	defer iter.Close()
   129  
   130  	err = iter.ForEach(func(ref *plumbing.Reference) error {
   131  		if i < skip {
   132  			i++
   133  			return nil
   134  		}
   135  		err := walkfn(ref.Hash().String(), string(ref.Name()))
   136  		i++
   137  		if err != nil {
   138  			return err
   139  		}
   140  		if limit != 0 && i >= skip+limit {
   141  			return storer.ErrStop
   142  		}
   143  		return nil
   144  	})
   145  	return i, err
   146  }
   147  
   148  // GetRefsBySha returns all references filtered with prefix that belong to a sha commit hash
   149  func (repo *Repository) GetRefsBySha(sha, prefix string) ([]string, error) {
   150  	var revList []string
   151  	iter, err := repo.gogitRepo.References()
   152  	if err != nil {
   153  		return nil, err
   154  	}
   155  	err = iter.ForEach(func(ref *plumbing.Reference) error {
   156  		if ref.Hash().String() == sha && strings.HasPrefix(string(ref.Name()), prefix) {
   157  			revList = append(revList, string(ref.Name()))
   158  		}
   159  		return nil
   160  	})
   161  	return revList, err
   162  }