code.gitea.io/gitea@v1.19.3/modules/git/repo_commit_nogogit.go (about)

     1  // Copyright 2020 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  //go:build !gogit
     5  
     6  package git
     7  
     8  import (
     9  	"bufio"
    10  	"errors"
    11  	"io"
    12  	"strings"
    13  
    14  	"code.gitea.io/gitea/modules/log"
    15  )
    16  
    17  // ResolveReference resolves a name to a reference
    18  func (repo *Repository) ResolveReference(name string) (string, error) {
    19  	stdout, _, err := NewCommand(repo.Ctx, "show-ref", "--hash").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
    20  	if err != nil {
    21  		if strings.Contains(err.Error(), "not a valid ref") {
    22  			return "", ErrNotExist{name, ""}
    23  		}
    24  		return "", err
    25  	}
    26  	stdout = strings.TrimSpace(stdout)
    27  	if stdout == "" {
    28  		return "", ErrNotExist{name, ""}
    29  	}
    30  
    31  	return stdout, nil
    32  }
    33  
    34  // GetRefCommitID returns the last commit ID string of given reference (branch or tag).
    35  func (repo *Repository) GetRefCommitID(name string) (string, error) {
    36  	wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
    37  	defer cancel()
    38  	_, err := wr.Write([]byte(name + "\n"))
    39  	if err != nil {
    40  		return "", err
    41  	}
    42  	shaBs, _, _, err := ReadBatchLine(rd)
    43  	if IsErrNotExist(err) {
    44  		return "", ErrNotExist{name, ""}
    45  	}
    46  
    47  	return string(shaBs), nil
    48  }
    49  
    50  // SetReference sets the commit ID string of given reference (e.g. branch or tag).
    51  func (repo *Repository) SetReference(name, commitID string) error {
    52  	_, _, err := NewCommand(repo.Ctx, "update-ref").AddDynamicArguments(name, commitID).RunStdString(&RunOpts{Dir: repo.Path})
    53  	return err
    54  }
    55  
    56  // RemoveReference removes the given reference (e.g. branch or tag).
    57  func (repo *Repository) RemoveReference(name string) error {
    58  	_, _, err := NewCommand(repo.Ctx, "update-ref", "--no-deref", "-d").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
    59  	return err
    60  }
    61  
    62  // IsCommitExist returns true if given commit exists in current repository.
    63  func (repo *Repository) IsCommitExist(name string) bool {
    64  	_, _, err := NewCommand(repo.Ctx, "cat-file", "-e").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
    65  	return err == nil
    66  }
    67  
    68  func (repo *Repository) getCommit(id SHA1) (*Commit, error) {
    69  	wr, rd, cancel := repo.CatFileBatch(repo.Ctx)
    70  	defer cancel()
    71  
    72  	_, _ = wr.Write([]byte(id.String() + "\n"))
    73  
    74  	return repo.getCommitFromBatchReader(rd, id)
    75  }
    76  
    77  func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Commit, error) {
    78  	_, typ, size, err := ReadBatchLine(rd)
    79  	if err != nil {
    80  		if errors.Is(err, io.EOF) || IsErrNotExist(err) {
    81  			return nil, ErrNotExist{ID: id.String()}
    82  		}
    83  		return nil, err
    84  	}
    85  
    86  	switch typ {
    87  	case "missing":
    88  		return nil, ErrNotExist{ID: id.String()}
    89  	case "tag":
    90  		// then we need to parse the tag
    91  		// and load the commit
    92  		data, err := io.ReadAll(io.LimitReader(rd, size))
    93  		if err != nil {
    94  			return nil, err
    95  		}
    96  		_, err = rd.Discard(1)
    97  		if err != nil {
    98  			return nil, err
    99  		}
   100  		tag, err := parseTagData(data)
   101  		if err != nil {
   102  			return nil, err
   103  		}
   104  
   105  		commit, err := tag.Commit(repo)
   106  		if err != nil {
   107  			return nil, err
   108  		}
   109  
   110  		return commit, nil
   111  	case "commit":
   112  		commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
   113  		if err != nil {
   114  			return nil, err
   115  		}
   116  		_, err = rd.Discard(1)
   117  		if err != nil {
   118  			return nil, err
   119  		}
   120  
   121  		return commit, nil
   122  	default:
   123  		log.Debug("Unknown typ: %s", typ)
   124  		_, err = rd.Discard(int(size) + 1)
   125  		if err != nil {
   126  			return nil, err
   127  		}
   128  		return nil, ErrNotExist{
   129  			ID: id.String(),
   130  		}
   131  	}
   132  }
   133  
   134  // ConvertToSHA1 returns a Hash object from a potential ID string
   135  func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) {
   136  	if len(commitID) == SHAFullLength && IsValidSHAPattern(commitID) {
   137  		sha1, err := NewIDFromString(commitID)
   138  		if err == nil {
   139  			return sha1, nil
   140  		}
   141  	}
   142  
   143  	wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
   144  	defer cancel()
   145  	_, err := wr.Write([]byte(commitID + "\n"))
   146  	if err != nil {
   147  		return SHA1{}, err
   148  	}
   149  	sha, _, _, err := ReadBatchLine(rd)
   150  	if err != nil {
   151  		if IsErrNotExist(err) {
   152  			return SHA1{}, ErrNotExist{commitID, ""}
   153  		}
   154  		return SHA1{}, err
   155  	}
   156  
   157  	return MustIDFromString(string(sha)), nil
   158  }