aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing
diff options
context:
space:
mode:
authorPaulo Gomes <pjbgf@linux.com>2023-04-11 21:00:47 +0100
committerGitHub <noreply@github.com>2023-04-11 21:00:47 +0100
commitd5b1afd3cc786e56a90cec910b79815ed3b23cc7 (patch)
tree4e0b93ea480fdea37761d2e879a073ce6f5c1747 /plumbing
parentce62f3e9ff86270538a514a68d3bd5563a733e3b (diff)
parent8e8281008ee98e9864fa9597be3e16aaecdf9891 (diff)
downloadgo-git-d5b1afd3cc786e56a90cec910b79815ed3b23cc7.tar.gz
Merge pull request #707 from pjbgf/experimental-sha256
*: Add support for initializing SHA256 repositories
Diffstat (limited to 'plumbing')
-rw-r--r--plumbing/format/commitgraph/encoder.go7
-rw-r--r--plumbing/format/config/format.go53
-rw-r--r--plumbing/format/idxfile/decoder.go3
-rw-r--r--plumbing/format/idxfile/encoder.go7
-rw-r--r--plumbing/format/idxfile/idxfile.go5
-rw-r--r--plumbing/format/index/decoder.go3
-rw-r--r--plumbing/format/index/encoder.go3
-rw-r--r--plumbing/format/packfile/encoder.go3
-rw-r--r--plumbing/format/packfile/encoder_test.go9
-rw-r--r--plumbing/format/packfile/scanner_test.go3
-rw-r--r--plumbing/hash.go14
-rw-r--r--plumbing/hash/hash.go3
-rw-r--r--plumbing/hash/hash_sha1.go15
-rw-r--r--plumbing/hash/hash_sha256.go15
-rw-r--r--plumbing/protocol/packp/ulreq_decode_test.go5
15 files changed, 117 insertions, 31 deletions
diff --git a/plumbing/format/commitgraph/encoder.go b/plumbing/format/commitgraph/encoder.go
index bcf7d03..f61025b 100644
--- a/plumbing/format/commitgraph/encoder.go
+++ b/plumbing/format/commitgraph/encoder.go
@@ -1,7 +1,6 @@
package commitgraph
import (
- "crypto"
"io"
"github.com/go-git/go-git/v5/plumbing"
@@ -17,7 +16,7 @@ type Encoder struct {
// NewEncoder returns a new stream encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
- h := hash.New(crypto.SHA1)
+ h := hash.New(hash.CryptoType)
mw := io.MultiWriter(w, h)
return &Encoder{mw, h}
}
@@ -31,7 +30,7 @@ func (e *Encoder) Encode(idx Index) error {
hashToIndex, fanout, extraEdgesCount := e.prepare(idx, hashes)
chunkSignatures := [][]byte{oidFanoutSignature, oidLookupSignature, commitDataSignature}
- chunkSizes := []uint64{4 * 256, uint64(len(hashes)) * 20, uint64(len(hashes)) * 36}
+ chunkSizes := []uint64{4 * 256, uint64(len(hashes)) * hash.Size, uint64(len(hashes)) * 36}
if extraEdgesCount > 0 {
chunkSignatures = append(chunkSignatures, extraEdgeListSignature)
chunkSizes = append(chunkSizes, uint64(extraEdgesCount)*4)
@@ -183,6 +182,6 @@ func (e *Encoder) encodeExtraEdges(extraEdges []uint32) (err error) {
}
func (e *Encoder) encodeChecksum() error {
- _, err := e.Write(e.hash.Sum(nil)[:20])
+ _, err := e.Write(e.hash.Sum(nil)[:hash.Size])
return err
}
diff --git a/plumbing/format/config/format.go b/plumbing/format/config/format.go
new file mode 100644
index 0000000..4873ea9
--- /dev/null
+++ b/plumbing/format/config/format.go
@@ -0,0 +1,53 @@
+package config
+
+// RepositoryFormatVersion represents the repository format version,
+// as per defined at:
+//
+// https://git-scm.com/docs/repository-version
+type RepositoryFormatVersion string
+
+const (
+ // Version_0 is the format defined by the initial version of git,
+ // including but not limited to the format of the repository
+ // directory, the repository configuration file, and the object
+ // and ref storage.
+ //
+ // Specifying the complete behavior of git is beyond the scope
+ // of this document.
+ Version_0 = "0"
+
+ // Version_1 is identical to version 0, with the following exceptions:
+ //
+ // 1. When reading the core.repositoryformatversion variable, a git
+ // implementation which supports version 1 MUST also read any
+ // configuration keys found in the extensions section of the
+ // configuration file.
+ //
+ // 2. If a version-1 repository specifies any extensions.* keys that
+ // the running git has not implemented, the operation MUST NOT proceed.
+ // Similarly, if the value of any known key is not understood by the
+ // implementation, the operation MUST NOT proceed.
+ //
+ // Note that if no extensions are specified in the config file, then
+ // core.repositoryformatversion SHOULD be set to 0 (setting it to 1 provides
+ // no benefit, and makes the repository incompatible with older
+ // implementations of git).
+ Version_1 = "1"
+
+ // DefaultRepositoryFormatVersion holds the default repository format version.
+ DefaultRepositoryFormatVersion = Version_0
+)
+
+// ObjectFormat defines the object format.
+type ObjectFormat string
+
+const (
+ // SHA1 represents the object format used for SHA1.
+ SHA1 ObjectFormat = "sha1"
+
+ // SHA256 represents the object format used for SHA256.
+ SHA256 ObjectFormat = "sha256"
+
+ // DefaultObjectFormat holds the default object format.
+ DefaultObjectFormat = SHA1
+)
diff --git a/plumbing/format/idxfile/decoder.go b/plumbing/format/idxfile/decoder.go
index 51a3904..9afdce3 100644
--- a/plumbing/format/idxfile/decoder.go
+++ b/plumbing/format/idxfile/decoder.go
@@ -6,6 +6,7 @@ import (
"errors"
"io"
+ "github.com/go-git/go-git/v5/plumbing/hash"
"github.com/go-git/go-git/v5/utils/binary"
)
@@ -19,7 +20,7 @@ var (
const (
fanout = 256
- objectIDLength = 20
+ objectIDLength = hash.Size
)
// Decoder reads and decodes idx files from an input stream.
diff --git a/plumbing/format/idxfile/encoder.go b/plumbing/format/idxfile/encoder.go
index 6ac445f..7514737 100644
--- a/plumbing/format/idxfile/encoder.go
+++ b/plumbing/format/idxfile/encoder.go
@@ -1,7 +1,6 @@
package idxfile
import (
- "crypto"
"io"
"github.com/go-git/go-git/v5/plumbing/hash"
@@ -16,7 +15,7 @@ type Encoder struct {
// NewEncoder returns a new stream encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
- h := hash.New(crypto.SHA1)
+ h := hash.New(hash.CryptoType)
mw := io.MultiWriter(w, h)
return &Encoder{mw, h}
}
@@ -133,10 +132,10 @@ func (e *Encoder) encodeChecksums(idx *MemoryIndex) (int, error) {
return 0, err
}
- copy(idx.IdxChecksum[:], e.hash.Sum(nil)[:20])
+ copy(idx.IdxChecksum[:], e.hash.Sum(nil)[:hash.Size])
if _, err := e.Write(idx.IdxChecksum[:]); err != nil {
return 0, err
}
- return 40, nil
+ return hash.HexSize, nil
}
diff --git a/plumbing/format/idxfile/idxfile.go b/plumbing/format/idxfile/idxfile.go
index 64dd8dc..9237a74 100644
--- a/plumbing/format/idxfile/idxfile.go
+++ b/plumbing/format/idxfile/idxfile.go
@@ -8,6 +8,7 @@ import (
encbin "encoding/binary"
"github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/hash"
)
const (
@@ -53,8 +54,8 @@ type MemoryIndex struct {
Offset32 [][]byte
CRC32 [][]byte
Offset64 []byte
- PackfileChecksum [20]byte
- IdxChecksum [20]byte
+ PackfileChecksum [hash.Size]byte
+ IdxChecksum [hash.Size]byte
offsetHash map[int64]plumbing.Hash
offsetHashIsFull bool
diff --git a/plumbing/format/index/decoder.go b/plumbing/format/index/decoder.go
index c4da20c..8834e25 100644
--- a/plumbing/format/index/decoder.go
+++ b/plumbing/format/index/decoder.go
@@ -3,7 +3,6 @@ package index
import (
"bufio"
"bytes"
- "crypto"
"errors"
"io"
"io/ioutil"
@@ -49,7 +48,7 @@ type Decoder struct {
// NewDecoder returns a new decoder that reads from r.
func NewDecoder(r io.Reader) *Decoder {
- h := hash.New(crypto.SHA1)
+ h := hash.New(hash.CryptoType)
return &Decoder{
r: io.TeeReader(r, h),
hash: h,
diff --git a/plumbing/format/index/encoder.go b/plumbing/format/index/encoder.go
index a915378..fa2d814 100644
--- a/plumbing/format/index/encoder.go
+++ b/plumbing/format/index/encoder.go
@@ -2,7 +2,6 @@ package index
import (
"bytes"
- "crypto"
"errors"
"io"
"sort"
@@ -29,7 +28,7 @@ type Encoder struct {
// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
- h := hash.New(crypto.SHA1)
+ h := hash.New(hash.CryptoType)
mw := io.MultiWriter(w, h)
return &Encoder{mw, h}
}
diff --git a/plumbing/format/packfile/encoder.go b/plumbing/format/packfile/encoder.go
index a8a7e96..c9d19b3 100644
--- a/plumbing/format/packfile/encoder.go
+++ b/plumbing/format/packfile/encoder.go
@@ -2,7 +2,6 @@ package packfile
import (
"compress/zlib"
- "crypto"
"fmt"
"io"
@@ -29,7 +28,7 @@ type Encoder struct {
// OFSDeltaObject. To use Reference deltas, set useRefDeltas to true.
func NewEncoder(w io.Writer, s storer.EncodedObjectStorer, useRefDeltas bool) *Encoder {
h := plumbing.Hasher{
- Hash: hash.New(crypto.SHA1),
+ Hash: hash.New(hash.CryptoType),
}
mw := io.MultiWriter(w, h)
ow := newOffsetWriter(mw)
diff --git a/plumbing/format/packfile/encoder_test.go b/plumbing/format/packfile/encoder_test.go
index c9d49c3..902d8cc 100644
--- a/plumbing/format/packfile/encoder_test.go
+++ b/plumbing/format/packfile/encoder_test.go
@@ -7,6 +7,7 @@ import (
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/idxfile"
+ "github.com/go-git/go-git/v5/plumbing/hash"
"github.com/go-git/go-git/v5/storage/memory"
"github.com/go-git/go-billy/v5/memfs"
@@ -30,10 +31,10 @@ func (s *EncoderSuite) SetUpTest(c *C) {
}
func (s *EncoderSuite) TestCorrectPackHeader(c *C) {
- hash, err := s.enc.Encode([]plumbing.Hash{}, 10)
+ h, err := s.enc.Encode([]plumbing.Hash{}, 10)
c.Assert(err, IsNil)
- hb := [20]byte(hash)
+ hb := [hash.Size]byte(h)
// PACK + VERSION + OBJECTS + HASH
expectedResult := []byte{'P', 'A', 'C', 'K', 0, 0, 0, 2, 0, 0, 0, 0}
@@ -51,7 +52,7 @@ func (s *EncoderSuite) TestCorrectPackWithOneEmptyObject(c *C) {
_, err := s.store.SetEncodedObject(o)
c.Assert(err, IsNil)
- hash, err := s.enc.Encode([]plumbing.Hash{o.Hash()}, 10)
+ h, err := s.enc.Encode([]plumbing.Hash{o.Hash()}, 10)
c.Assert(err, IsNil)
// PACK + VERSION(2) + OBJECT NUMBER(1)
@@ -64,7 +65,7 @@ func (s *EncoderSuite) TestCorrectPackWithOneEmptyObject(c *C) {
[]byte{120, 156, 1, 0, 0, 255, 255, 0, 0, 0, 1}...)
// + HASH
- hb := [20]byte(hash)
+ hb := [hash.Size]byte(h)
expectedResult = append(expectedResult, hb[:]...)
result := s.buf.Bytes()
diff --git a/plumbing/format/packfile/scanner_test.go b/plumbing/format/packfile/scanner_test.go
index 892a27c..9dcc359 100644
--- a/plumbing/format/packfile/scanner_test.go
+++ b/plumbing/format/packfile/scanner_test.go
@@ -6,6 +6,7 @@ import (
fixtures "github.com/go-git/go-git-fixtures/v4"
"github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/hash"
. "gopkg.in/check.v1"
)
@@ -71,7 +72,7 @@ func (s *ScannerSuite) testNextObjectHeader(c *C, tag string,
n, err := p.Checksum()
c.Assert(err, IsNil)
- c.Assert(n, HasLen, 20)
+ c.Assert(n, HasLen, hash.Size)
}
func (s *ScannerSuite) TestNextObjectHeaderWithOutReadObject(c *C) {
diff --git a/plumbing/hash.go b/plumbing/hash.go
index 2fab759..39bb73f 100644
--- a/plumbing/hash.go
+++ b/plumbing/hash.go
@@ -2,7 +2,6 @@ package plumbing
import (
"bytes"
- "crypto"
"encoding/hex"
"sort"
"strconv"
@@ -11,7 +10,7 @@ import (
)
// Hash SHA1 hashed content
-type Hash [20]byte
+type Hash [hash.Size]byte
// ZeroHash is Hash with value zero
var ZeroHash Hash
@@ -47,7 +46,7 @@ type Hasher struct {
}
func NewHasher(t ObjectType, size int64) Hasher {
- h := Hasher{hash.New(crypto.SHA1)}
+ h := Hasher{hash.New(hash.CryptoType)}
h.Write(t.Bytes())
h.Write([]byte(" "))
h.Write([]byte(strconv.FormatInt(size, 10)))
@@ -75,10 +74,11 @@ func (p HashSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// IsHash returns true if the given string is a valid hash.
func IsHash(s string) bool {
- if len(s) != 40 {
+ switch len(s) {
+ case hash.HexSize:
+ _, err := hex.DecodeString(s)
+ return err == nil
+ default:
return false
}
-
- _, err := hex.DecodeString(s)
- return err == nil
}
diff --git a/plumbing/hash/hash.go b/plumbing/hash/hash.go
index 80e4b5f..82d1856 100644
--- a/plumbing/hash/hash.go
+++ b/plumbing/hash/hash.go
@@ -21,6 +21,7 @@ func init() {
// that registers new algorithms to avoid side effects.
func reset() {
algos[crypto.SHA1] = sha1cd.New
+ algos[crypto.SHA256] = crypto.SHA256.New
}
// RegisterHash allows for the hash algorithm used to be overriden.
@@ -34,6 +35,8 @@ func RegisterHash(h crypto.Hash, f func() hash.Hash) error {
switch h {
case crypto.SHA1:
algos[h] = f
+ case crypto.SHA256:
+ algos[h] = f
default:
return fmt.Errorf("unsupported hash function: %v", h)
}
diff --git a/plumbing/hash/hash_sha1.go b/plumbing/hash/hash_sha1.go
new file mode 100644
index 0000000..e3cb60f
--- /dev/null
+++ b/plumbing/hash/hash_sha1.go
@@ -0,0 +1,15 @@
+//go:build !sha256
+// +build !sha256
+
+package hash
+
+import "crypto"
+
+const (
+ // CryptoType defines what hash algorithm is being used.
+ CryptoType = crypto.SHA1
+ // Size defines the amount of bytes the hash yields.
+ Size = 20
+ // HexSize defines the strings size of the hash when represented in hexadecimal.
+ HexSize = 40
+)
diff --git a/plumbing/hash/hash_sha256.go b/plumbing/hash/hash_sha256.go
new file mode 100644
index 0000000..1c52b89
--- /dev/null
+++ b/plumbing/hash/hash_sha256.go
@@ -0,0 +1,15 @@
+//go:build sha256
+// +build sha256
+
+package hash
+
+import "crypto"
+
+const (
+ // CryptoType defines what hash algorithm is being used.
+ CryptoType = crypto.SHA256
+ // Size defines the amount of bytes the hash yields.
+ Size = 32
+ // HexSize defines the strings size of the hash when represented in hexadecimal.
+ HexSize = 64
+)
diff --git a/plumbing/protocol/packp/ulreq_decode_test.go b/plumbing/protocol/packp/ulreq_decode_test.go
index 9628f0f..efcc7b4 100644
--- a/plumbing/protocol/packp/ulreq_decode_test.go
+++ b/plumbing/protocol/packp/ulreq_decode_test.go
@@ -8,6 +8,7 @@ import (
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/pktline"
+ "github.com/go-git/go-git/v5/plumbing/hash"
"github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
. "gopkg.in/check.v1"
@@ -119,8 +120,8 @@ type byHash []plumbing.Hash
func (a byHash) Len() int { return len(a) }
func (a byHash) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byHash) Less(i, j int) bool {
- ii := [20]byte(a[i])
- jj := [20]byte(a[j])
+ ii := [hash.Size]byte(a[i])
+ jj := [hash.Size]byte(a[j])
return bytes.Compare(ii[:], jj[:]) < 0
}