diff options
| author | 2025-11-15 00:00:00 +0000 | |
|---|---|---|
| committer | 2025-11-15 00:00:00 +0000 | |
| commit | 6655e9f74eac800e26f57ebdb143111726e8b73d (patch) | |
| tree | db36fffb1dac361f0ca42023d747081fefaeb14f | |
| parent | Add initial support for multi pack indexes (diff) | |
| signature | ||
Use SHA-256 by default
| -rw-r--r-- | .build.yml | 1 | ||||
| -rw-r--r-- | README.md | 16 | ||||
| -rw-r--r-- | hash.go | 7 | ||||
| -rw-r--r-- | hash_sha1.go | 11 | ||||
| -rw-r--r-- | hash_sha256.go | 11 | ||||
| -rw-r--r-- | hash_test.go | 19 | ||||
| -rw-r--r-- | objects_test.go | 7 | ||||
| -rw-r--r-- | pack_test.go | 2 |
8 files changed, 50 insertions, 24 deletions
@@ -6,4 +6,5 @@ tasks: - build: | cd furgit go test -v + go test -v -tags sha1 golangci-lint run . @@ -26,7 +26,8 @@ used repos (including their `.idx` and `.pack` cache) for rapid access. We currently do not intend to support flexible storage backends such as [storers in go-git](https://pkg.go.dev/github.com/go-git/go-git/v5/plumbing/storer); -a standard UNIX-like filesystem is expected. +a standard UNIX-like filesystem with +[syscall.Mmap](https://pkg.go.dev/syscall#Mmap) is expected. ## Performance @@ -40,15 +41,12 @@ it is: * approximately 10 times faster than [libgit2](https://libgit2.org), and * approximately 1000 times faster than [go-git](https://github.com/go-git/go-git). -## Compatibility +## Hash algorithm -* We only aim to support UNIX-like operating systems that have - [syscall.Mmap](https://pkg.go.dev/syscall#Mmap). -* Currently, this version of Furgit only supports SHA-1 hashes. - You may edit two lines in `hash.go` to trivially switch to SHA-256. - The upstream Villosa project only uses SHA-256 hashes. - We intend to make this library easily interoperable across hash - formats, but that's not the primary goal for now. +Furgit uses SHA-256 by default. To switch to SHA-1, use the `sha1` build tag. + +There will be future research to investigate potentially supporting both +algorithms in one build of the library (likely heavily using generics). ## Development @@ -1,17 +1,10 @@ package furgit import ( - "crypto/sha1" "encoding/hex" "fmt" ) -// To change the hash algorithm you probably only need to change these two lines... - -const HashSize = sha1.Size - -var newHash = sha1.Sum - // Hash represents a Git object identifier. type Hash [HashSize]byte diff --git a/hash_sha1.go b/hash_sha1.go new file mode 100644 index 00000000..ac2f52b5 --- /dev/null +++ b/hash_sha1.go @@ -0,0 +1,11 @@ +//go:build sha1 + +package furgit + +import ( + "crypto/sha1" +) + +const HashSize = sha1.Size + +var newHash = sha1.Sum diff --git a/hash_sha256.go b/hash_sha256.go new file mode 100644 index 00000000..e35eab34 --- /dev/null +++ b/hash_sha256.go @@ -0,0 +1,11 @@ +//go:build !sha1 + +package furgit + +import ( + "crypto/sha256" +) + +const HashSize = sha256.Size + +var newHash = sha256.Sum256 diff --git a/hash_test.go b/hash_test.go index 95660d88..e09eadfb 100644 --- a/hash_test.go +++ b/hash_test.go @@ -1,21 +1,30 @@ package furgit -import "testing" +import ( + "strings" + "testing" +) func TestParseHashValidAndInvalid(t *testing.T) { - const hex40 = "0123456789abcdef0123456789abcdef01234567" - id, err := ParseHash(hex40) + pattern := "0123456789abcdef" + repeats := (HashSize*2 + len(pattern) - 1) / len(pattern) + hexStr := strings.Repeat(pattern, repeats)[:HashSize*2] + + id, err := ParseHash(hexStr) if err != nil { t.Fatalf("ParseHash returned error: %v", err) } - if got := id.String(); got != hex40 { + + if got := id.String(); got != hexStr { t.Fatalf("unexpected String result: %q", got) } if _, err := ParseHash("abcd"); err == nil { t.Fatal("expected error for short hash") } - if _, err := ParseHash("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"); err == nil { + + badHex := strings.Repeat("z", HashSize*2) + if _, err := ParseHash(badHex); err == nil { t.Fatal("expected error for non-hex input") } } diff --git a/objects_test.go b/objects_test.go index b5b3c5b9..2bb0d486 100644 --- a/objects_test.go +++ b/objects_test.go @@ -26,8 +26,11 @@ func hashWithByte(fill byte) Hash { } func TestLoosePathUsesExpectedLayout(t *testing.T) { - id := mustHash(t, "0123456789abcdef0123456789abcdef01234567") - expect := filepath.Join("objects", "01", "23456789abcdef0123456789abcdef01234567") + pattern := "0123456789abcdef" + repeats := (HashSize*2 + len(pattern) - 1) / len(pattern) + hexStr := strings.Repeat(pattern, repeats)[:HashSize*2] + id := mustHash(t, hexStr) + expect := filepath.Join("objects", hexStr[:2], hexStr[2:]) if got := loosePath(id); got != expect { t.Fatalf("unexpected loose path: %q", got) } diff --git a/pack_test.go b/pack_test.go index 5661e322..1dae5d3a 100644 --- a/pack_test.go +++ b/pack_test.go @@ -183,7 +183,7 @@ func buildTestPackIndexBuffer(hash Hash, offset uint32) []byte { off32 := make([]byte, 4) binary.BigEndian.PutUint32(off32, offset) buf.Write(off32) - buf.Write(make([]byte, 40)) + buf.Write(make([]byte, 2*HashSize)) return buf.Bytes() } |
