aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Runxi Yu2025-11-15 00:00:00 +0000
committerGravatar Runxi Yu2025-11-15 00:00:00 +0000
commit6655e9f74eac800e26f57ebdb143111726e8b73d (patch)
treedb36fffb1dac361f0ca42023d747081fefaeb14f
parentAdd initial support for multi pack indexes (diff)
signature
Use SHA-256 by default
-rw-r--r--.build.yml1
-rw-r--r--README.md16
-rw-r--r--hash.go7
-rw-r--r--hash_sha1.go11
-rw-r--r--hash_sha256.go11
-rw-r--r--hash_test.go19
-rw-r--r--objects_test.go7
-rw-r--r--pack_test.go2
8 files changed, 50 insertions, 24 deletions
diff --git a/.build.yml b/.build.yml
index de92b74f..10dccee0 100644
--- a/.build.yml
+++ b/.build.yml
@@ -6,4 +6,5 @@ tasks:
- build: |
cd furgit
go test -v
+ go test -v -tags sha1
golangci-lint run .
diff --git a/README.md b/README.md
index 95d93532..b8ebd0de 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/hash.go b/hash.go
index f03866f1..3c6ff6ac 100644
--- a/hash.go
+++ b/hash.go
@@ -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()
}