code.gitea.io/gitea@v1.22.3/modules/git/object_id.go (about)

     1  // Copyright 2023 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package git
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/hex"
     9  	"fmt"
    10  )
    11  
    12  type ObjectID interface {
    13  	String() string
    14  	IsZero() bool
    15  	RawValue() []byte
    16  	Type() ObjectFormat
    17  }
    18  
    19  type Sha1Hash [20]byte
    20  
    21  func (h *Sha1Hash) String() string {
    22  	return hex.EncodeToString(h[:])
    23  }
    24  
    25  func (h *Sha1Hash) IsZero() bool {
    26  	empty := Sha1Hash{}
    27  	return bytes.Equal(empty[:], h[:])
    28  }
    29  func (h *Sha1Hash) RawValue() []byte { return h[:] }
    30  func (*Sha1Hash) Type() ObjectFormat { return Sha1ObjectFormat }
    31  
    32  var _ ObjectID = &Sha1Hash{}
    33  
    34  func MustIDFromString(hexHash string) ObjectID {
    35  	id, err := NewIDFromString(hexHash)
    36  	if err != nil {
    37  		panic(err)
    38  	}
    39  	return id
    40  }
    41  
    42  type Sha256Hash [32]byte
    43  
    44  func (h *Sha256Hash) String() string {
    45  	return hex.EncodeToString(h[:])
    46  }
    47  
    48  func (h *Sha256Hash) IsZero() bool {
    49  	empty := Sha256Hash{}
    50  	return bytes.Equal(empty[:], h[:])
    51  }
    52  func (h *Sha256Hash) RawValue() []byte { return h[:] }
    53  func (*Sha256Hash) Type() ObjectFormat { return Sha256ObjectFormat }
    54  
    55  func NewIDFromString(hexHash string) (ObjectID, error) {
    56  	var theObjectFormat ObjectFormat
    57  	for _, objectFormat := range DefaultFeatures().SupportedObjectFormats {
    58  		if len(hexHash) == objectFormat.FullLength() {
    59  			theObjectFormat = objectFormat
    60  			break
    61  		}
    62  	}
    63  
    64  	if theObjectFormat == nil {
    65  		return nil, fmt.Errorf("length %d has no matched object format: %s", len(hexHash), hexHash)
    66  	}
    67  
    68  	b, err := hex.DecodeString(hexHash)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	if len(b) != theObjectFormat.FullLength()/2 {
    74  		return theObjectFormat.EmptyObjectID(), fmt.Errorf("length must be %d: %v", theObjectFormat.FullLength(), b)
    75  	}
    76  	return theObjectFormat.MustID(b), nil
    77  }
    78  
    79  func IsEmptyCommitID(commitID string) bool {
    80  	if commitID == "" {
    81  		return true
    82  	}
    83  
    84  	id, err := NewIDFromString(commitID)
    85  	if err != nil {
    86  		return false
    87  	}
    88  
    89  	return id.IsZero()
    90  }
    91  
    92  // ComputeBlobHash compute the hash for a given blob content
    93  func ComputeBlobHash(hashType ObjectFormat, content []byte) ObjectID {
    94  	return hashType.ComputeHash(ObjectBlob, content)
    95  }
    96  
    97  type ErrInvalidSHA struct {
    98  	SHA string
    99  }
   100  
   101  func (err ErrInvalidSHA) Error() string {
   102  	return fmt.Sprintf("invalid sha: %s", err.SHA)
   103  }