code.gitea.io/gitea@v1.22.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, err := repo.CatFileBatchCheck(repo.Ctx)
    37  	if err != nil {
    38  		return "", err
    39  	}
    40  	defer cancel()
    41  	_, err = wr.Write([]byte(name + "\n"))
    42  	if err != nil {
    43  		return "", err
    44  	}
    45  	shaBs, _, _, err := ReadBatchLine(rd)
    46  	if IsErrNotExist(err) {
    47  		return "", ErrNotExist{name, ""}
    48  	}
    49  
    50  	return string(shaBs), nil
    51  }
    52  
    53  // SetReference sets the commit ID string of given reference (e.g. branch or tag).
    54  func (repo *Repository) SetReference(name, commitID string) error {
    55  	_, _, err := NewCommand(repo.Ctx, "update-ref").AddDynamicArguments(name, commitID).RunStdString(&RunOpts{Dir: repo.Path})
    56  	return err
    57  }
    58  
    59  // RemoveReference removes the given reference (e.g. branch or tag).
    60  func (repo *Repository) RemoveReference(name string) error {
    61  	_, _, err := NewCommand(repo.Ctx, "update-ref", "--no-deref", "-d").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
    62  	return err
    63  }
    64  
    65  // IsCommitExist returns true if given commit exists in current repository.
    66  func (repo *Repository) IsCommitExist(name string) bool {
    67  	if err := ensureValidGitRepository(repo.Ctx, repo.Path); err != nil {
    68  		log.Error("IsCommitExist: %v", err)
    69  		return false
    70  	}
    71  	_, _, err := NewCommand(repo.Ctx, "cat-file", "-e").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
    72  	return err == nil
    73  }
    74  
    75  func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
    76  	wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	defer cancel()
    81  
    82  	_, _ = wr.Write([]byte(id.String() + "\n"))
    83  
    84  	return repo.getCommitFromBatchReader(rd, id)
    85  }
    86  
    87  func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) (*Commit, error) {
    88  	_, typ, size, err := ReadBatchLine(rd)
    89  	if err != nil {
    90  		if errors.Is(err, io.EOF) || IsErrNotExist(err) {
    91  			return nil, ErrNotExist{ID: id.String()}
    92  		}
    93  		return nil, err
    94  	}
    95  
    96  	switch typ {
    97  	case "missing":
    98  		return nil, ErrNotExist{ID: id.String()}
    99  	case "tag":
   100  		// then we need to parse the tag
   101  		// and load the commit
   102  		data, err := io.ReadAll(io.LimitReader(rd, size))
   103  		if err != nil {
   104  			return nil, err
   105  		}
   106  		_, err = rd.Discard(1)
   107  		if err != nil {
   108  			return nil, err
   109  		}
   110  		tag, err := parseTagData(id.Type(), data)
   111  		if err != nil {
   112  			return nil, err
   113  		}
   114  
   115  		commit, err := tag.Commit(repo)
   116  		if err != nil {
   117  			return nil, err
   118  		}
   119  
   120  		return commit, nil
   121  	case "commit":
   122  		commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
   123  		if err != nil {
   124  			return nil, err
   125  		}
   126  		_, err = rd.Discard(1)
   127  		if err != nil {
   128  			return nil, err
   129  		}
   130  
   131  		return commit, nil
   132  	default:
   133  		log.Debug("Unknown typ: %s", typ)
   134  		if err := DiscardFull(rd, size+1); err != nil {
   135  			return nil, err
   136  		}
   137  		return nil, ErrNotExist{
   138  			ID: id.String(),
   139  		}
   140  	}
   141  }
   142  
   143  // ConvertToGitID returns a GitHash object from a potential ID string
   144  func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) {
   145  	objectFormat, err := repo.GetObjectFormat()
   146  	if err != nil {
   147  		return nil, err
   148  	}
   149  	if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) {
   150  		ID, err := NewIDFromString(commitID)
   151  		if err == nil {
   152  			return ID, nil
   153  		}
   154  	}
   155  
   156  	wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
   157  	if err != nil {
   158  		return nil, err
   159  	}
   160  	defer cancel()
   161  	_, err = wr.Write([]byte(commitID + "\n"))
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  	sha, _, _, err := ReadBatchLine(rd)
   166  	if err != nil {
   167  		if IsErrNotExist(err) {
   168  			return nil, ErrNotExist{commitID, ""}
   169  		}
   170  		return nil, err
   171  	}
   172  
   173  	return MustIDFromString(string(sha)), nil
   174  }