Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToon Claes <toon@gitlab.com>2022-08-16 18:30:33 +0300
committerToon Claes <toon@gitlab.com>2022-08-16 18:30:33 +0300
commit8263b2f7f00bb5197a1b97f2a420c5662af8e40c (patch)
tree3bdad03b19eb24a475e17d92f745fd93e1ee0ee6
parent4128e23ac5533b0f3548d4a627e8a3e19718be5f (diff)
parentcffaa1610ff5f2ac8d2b78a5f74d2f4e4a90a5bb (diff)
Merge branch 'pks-gitpipe-sha256' into 'master'
gitpipe: Support SHA256 object hash See merge request gitlab-org/gitaly!4798
-rw-r--r--internal/git/gitpipe/catfile_info.go10
-rw-r--r--internal/git/gitpipe/catfile_info_test.go98
-rw-r--r--internal/git/gitpipe/catfile_object_test.go59
-rw-r--r--internal/git/gitpipe/diff_tree.go2
-rw-r--r--internal/git/gitpipe/diff_tree_test.go240
-rw-r--r--internal/git/gitpipe/ls_tree.go10
-rw-r--r--internal/git/gitpipe/ls_tree_test.go217
-rw-r--r--internal/git/gitpipe/pipeline_test.go156
-rw-r--r--internal/git/gitpipe/revision_test.go397
-rw-r--r--internal/git/gitpipe/testhelper_test.go10
10 files changed, 694 insertions, 505 deletions
diff --git a/internal/git/gitpipe/catfile_info.go b/internal/git/gitpipe/catfile_info.go
index 8b4792378..3aec77cca 100644
--- a/internal/git/gitpipe/catfile_info.go
+++ b/internal/git/gitpipe/catfile_info.go
@@ -185,6 +185,14 @@ func CatfileInfoAllObjects(
go func() {
defer close(resultChan)
+ objectHash, err := repo.ObjectHash(ctx)
+ if err != nil {
+ sendCatfileInfoResult(ctx, resultChan, CatfileInfoResult{
+ err: fmt.Errorf("detecting object hash: %w", err),
+ })
+ return
+ }
+
var stderr bytes.Buffer
cmd, err := repo.Exec(ctx, git.SubCmd{
Name: "cat-file",
@@ -204,7 +212,7 @@ func CatfileInfoAllObjects(
reader := bufio.NewReader(cmd)
for {
- objectInfo, err := catfile.ParseObjectInfo(git.ObjectHashSHA1, reader)
+ objectInfo, err := catfile.ParseObjectInfo(objectHash, reader)
if err != nil {
if errors.Is(err, io.EOF) {
break
diff --git a/internal/git/gitpipe/catfile_info_test.go b/internal/git/gitpipe/catfile_info_test.go
index e9af6cfd7..94cf6a78d 100644
--- a/internal/git/gitpipe/catfile_info_test.go
+++ b/internal/git/gitpipe/catfile_info_test.go
@@ -1,15 +1,13 @@
-//go:build !gitaly_test_sha256
-
package gitpipe
import (
+ "bytes"
"context"
"errors"
"fmt"
"testing"
"github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
@@ -18,23 +16,27 @@ import (
"google.golang.org/grpc/metadata"
)
-const (
- lfsPointer1 = "0c304a93cb8430108629bbbcaa27db3343299bc0"
- lfsPointer2 = "f78df813119a79bfbe0442ab92540a61d3ab7ff3"
- lfsPointer3 = "bab31d249f78fba464d1b75799aad496cc07fa3b"
- lfsPointer4 = "125fcc9f6e33175cb278b9b2809154d2535fe19f"
-)
-
func TestCatfileInfo(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
cfg := testcfg.Build(t)
- repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
SkipCreationViaService: true,
- Seed: gittest.SeedGitLabTest,
})
repo := localrepo.NewTestRepo(t, cfg, repoProto)
+ blobA := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("a"), 133))
+ blobB := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("b"), 127))
+ blobC := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("c"), 127))
+ blobD := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("d"), 129))
+
+ blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("contents"))
+ treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "branch-test.txt", Mode: "100644", OID: blobID},
+ })
+
for _, tc := range []struct {
desc string
revlistInputs []RevisionResult
@@ -45,36 +47,36 @@ func TestCatfileInfo(t *testing.T) {
{
desc: "single blob",
revlistInputs: []RevisionResult{
- {OID: lfsPointer1},
+ {OID: blobA},
},
expectedResults: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}},
},
},
{
desc: "multiple blobs",
revlistInputs: []RevisionResult{
- {OID: lfsPointer1},
- {OID: lfsPointer2},
- {OID: lfsPointer3},
- {OID: lfsPointer4},
+ {OID: blobA},
+ {OID: blobB},
+ {OID: blobC},
+ {OID: blobD},
},
expectedResults: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobC, Type: "blob", Size: 127}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobD, Type: "blob", Size: 129}},
},
},
{
desc: "object name",
revlistInputs: []RevisionResult{
- {OID: "b95c0fad32f4361845f91d9ce4c1721b52b82793"},
- {OID: "93e123ac8a3e6a0b600953d7598af629dec7b735", ObjectName: []byte("branch-test.txt")},
+ {OID: treeID},
+ {OID: blobID, ObjectName: []byte("branch-test.txt")},
},
expectedResults: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: treeID, Type: "tree", Size: hashDependentObjectSize(43, 55)}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobID, Type: "blob", Size: 8}, ObjectName: []byte("branch-test.txt")},
},
},
{
@@ -87,20 +89,20 @@ func TestCatfileInfo(t *testing.T) {
{
desc: "mixed valid and invalid revision",
revlistInputs: []RevisionResult{
- {OID: lfsPointer1},
+ {OID: blobA},
{OID: "invalidobjectid"},
- {OID: lfsPointer2},
+ {OID: blobB},
},
expectedResults: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}},
},
expectedErr: errors.New("retrieving object info for \"invalidobjectid\": object not found"),
},
{
desc: "skip everything",
revlistInputs: []RevisionResult{
- {OID: lfsPointer1},
- {OID: lfsPointer2},
+ {OID: blobA},
+ {OID: blobB},
},
opts: []CatfileInfoOption{
WithSkipCatfileInfoResult(func(*catfile.ObjectInfo) bool { return true }),
@@ -109,30 +111,30 @@ func TestCatfileInfo(t *testing.T) {
{
desc: "skip one",
revlistInputs: []RevisionResult{
- {OID: lfsPointer1},
- {OID: lfsPointer2},
+ {OID: blobA},
+ {OID: blobB},
},
opts: []CatfileInfoOption{
WithSkipCatfileInfoResult(func(objectInfo *catfile.ObjectInfo) bool {
- return objectInfo.Oid == lfsPointer1
+ return objectInfo.Oid == blobA
}),
},
expectedResults: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}},
},
},
{
desc: "skip nothing",
revlistInputs: []RevisionResult{
- {OID: lfsPointer1},
- {OID: lfsPointer2},
+ {OID: blobA},
+ {OID: blobB},
},
opts: []CatfileInfoOption{
WithSkipCatfileInfoResult(func(*catfile.ObjectInfo) bool { return false }),
},
expectedResults: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}},
},
},
} {
@@ -175,15 +177,15 @@ func TestCatfileInfo(t *testing.T) {
defer objectInfoReaderCancel()
it, err := CatfileInfo(ctx, objectInfoReader, NewRevisionIterator(ctx, []RevisionResult{
- {OID: lfsPointer1},
- {OID: lfsPointer1},
+ {OID: blobA},
+ {OID: blobA},
}))
require.NoError(t, err)
require.True(t, it.Next())
require.NoError(t, it.Err())
require.Equal(t, CatfileInfoResult{
- ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133},
+ ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133},
}, it.Result())
cancel()
@@ -217,7 +219,7 @@ func TestCatfileInfo(t *testing.T) {
// not flushed after every object this means that the request is currently
// outstanding.
<-nextCh
- inputCh <- git.ObjectID(lfsPointer1)
+ inputCh <- blobA
// Wait for the pipeline to request the next object.
<-nextCh
@@ -233,7 +235,7 @@ func TestCatfileInfo(t *testing.T) {
cancel()
// Now we queue another request that should cause the pipeline to fail.
- inputCh <- git.ObjectID(lfsPointer1)
+ inputCh <- blobA
// Verify whether we can receive any more objects via the iterator. This should
// fail because the context got cancelled, but in any case it shouldn't block. Note
@@ -258,7 +260,7 @@ func TestCatfileInfo(t *testing.T) {
defer cancel()
input := []RevisionResult{
- {OID: lfsPointer1},
+ {OID: blobA},
}
it, err := CatfileInfo(ctx, objectInfoReader, NewRevisionIterator(ctx, input))
@@ -279,6 +281,8 @@ func TestCatfileInfo(t *testing.T) {
}
func TestCatfileInfoAllObjects(t *testing.T) {
+ t.Parallel()
+
cfg := testcfg.Build(t)
ctx := testhelper.Context(t)
@@ -297,8 +301,8 @@ func TestCatfileInfoAllObjects(t *testing.T) {
actualObjects := []CatfileInfoResult{
{ObjectInfo: &catfile.ObjectInfo{Oid: blob1, Type: "blob", Size: 6}},
{ObjectInfo: &catfile.ObjectInfo{Oid: blob2, Type: "blob", Size: 6}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: tree, Type: "tree", Size: 34}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: commit, Type: "commit", Size: 177}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: tree, Type: "tree", Size: hashDependentObjectSize(34, 46)}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: commit, Type: "commit", Size: hashDependentObjectSize(177, 201)}},
}
t.Run("successful", func(t *testing.T) {
diff --git a/internal/git/gitpipe/catfile_object_test.go b/internal/git/gitpipe/catfile_object_test.go
index 72c47c1f5..fe4f5d319 100644
--- a/internal/git/gitpipe/catfile_object_test.go
+++ b/internal/git/gitpipe/catfile_object_test.go
@@ -1,8 +1,7 @@
-//go:build !gitaly_test_sha256
-
package gitpipe
import (
+ "bytes"
"context"
"errors"
"fmt"
@@ -10,7 +9,6 @@ import (
"testing"
"github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
@@ -20,15 +18,26 @@ import (
)
func TestCatfileObject(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
cfg := testcfg.Build(t)
- repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
SkipCreationViaService: true,
- Seed: gittest.SeedGitLabTest,
})
repo := localrepo.NewTestRepo(t, cfg, repoProto)
+ blobA := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("a"), 133))
+ blobB := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("b"), 127))
+ blobC := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("c"), 127))
+ blobD := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("d"), 129))
+
+ blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("contents"))
+ treeID := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "branch-test.txt", Mode: "100644", OID: blobID},
+ })
+
for _, tc := range []struct {
desc string
catfileInfoInputs []CatfileInfoResult
@@ -38,36 +47,36 @@ func TestCatfileObject(t *testing.T) {
{
desc: "single blob",
catfileInfoInputs: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}},
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}},
},
},
{
desc: "multiple blobs",
catfileInfoInputs: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobC, Type: "blob", Size: 127}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobD, Type: "blob", Size: 129}},
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobC, Type: "blob", Size: 127}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobD, Type: "blob", Size: 129}}},
},
},
{
desc: "revlist result with object names",
catfileInfoInputs: []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: treeID, Type: "tree", Size: hashDependentObjectSize(43, 55)}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobID, Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")},
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}}, ObjectName: []byte("branch-test.txt")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: treeID, Type: "tree", Size: hashDependentObjectSize(43, 55)}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobID, Type: "blob", Size: 8}}, ObjectName: []byte("branch-test.txt")},
},
},
{
@@ -135,14 +144,14 @@ func TestCatfileObject(t *testing.T) {
defer objectReaderCancel()
it, err := CatfileObject(ctx, objectReader, NewCatfileInfoIterator(ctx, []CatfileInfoResult{
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}},
- {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 133}},
+ {ObjectInfo: &catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 127}},
}))
require.NoError(t, err)
require.True(t, it.Next())
require.NoError(t, it.Err())
- require.Equal(t, git.ObjectID(lfsPointer1), it.Result().ObjectID())
+ require.Equal(t, blobA, it.Result().ObjectID())
_, err = io.Copy(io.Discard, it.Result())
require.NoError(t, err)
@@ -178,7 +187,7 @@ func TestCatfileObject(t *testing.T) {
// not flushed after every object this means that the request is currently
// outstanding.
<-nextCh
- inputCh <- git.ObjectID(lfsPointer1)
+ inputCh <- blobA
// Wait for the pipeline to request the next object.
<-nextCh
@@ -194,7 +203,7 @@ func TestCatfileObject(t *testing.T) {
cancel()
// Now we queue another request that should cause the pipeline to fail.
- inputCh <- git.ObjectID(lfsPointer1)
+ inputCh <- blobA
// Verify whether we can receive any more objects via the iterator. This should
// fail because the context got cancelled, but in any case it shouldn't block. Note
@@ -219,7 +228,7 @@ func TestCatfileObject(t *testing.T) {
defer cancel()
input := []RevisionResult{
- {OID: lfsPointer1},
+ {OID: blobA},
}
it, err := CatfileObject(ctx, objectReader, NewRevisionIterator(ctx, input))
diff --git a/internal/git/gitpipe/diff_tree.go b/internal/git/gitpipe/diff_tree.go
index 5caecf55f..cf81a1ba3 100644
--- a/internal/git/gitpipe/diff_tree.go
+++ b/internal/git/gitpipe/diff_tree.go
@@ -46,7 +46,7 @@ func DiffTreeWithSkip(skipResult func(*RevisionResult) bool) DiffTreeOption {
// DiffTree runs git-diff-tree(1) between the two given revisions. The returned
// channel will contain the new object IDs listed by this command. For deleted
-// files this would be git.ObjectHashSHA1.ZeroOID. Cancelling the context will cause the
+// files this would be the all-zeroes object ID. Cancelling the context will cause the
// pipeline to be cancelled, too. By default, it will not recurse into subtrees.
func DiffTree(
ctx context.Context,
diff --git a/internal/git/gitpipe/diff_tree_test.go b/internal/git/gitpipe/diff_tree_test.go
index f2cac6a38..ca29d509a 100644
--- a/internal/git/gitpipe/diff_tree_test.go
+++ b/internal/git/gitpipe/diff_tree_test.go
@@ -1,12 +1,12 @@
-//go:build !gitaly_test_sha256
-
package gitpipe
import (
+ "bytes"
"errors"
"testing"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
@@ -14,108 +14,191 @@ import (
)
func TestDiffTree(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
cfg := testcfg.Build(t)
- repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
- SkipCreationViaService: true,
- Seed: gittest.SeedGitLabTest,
- })
- repo := localrepo.NewTestRepo(t, cfg, repoProto)
-
for _, tc := range []struct {
- desc string
- leftRevision string
- rightRevision string
- options []DiffTreeOption
- expectedResults []RevisionResult
- expectedErr error
+ desc string
+ setup func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult)
+ options []DiffTreeOption
+ expectedErr error
}{
{
- desc: "single file",
- leftRevision: "b83d6e391c22777fca1ed3012fce84f633d7fed0",
- rightRevision: "4a24d82dbca5c11c61556f3b35ca472b7463187e",
- expectedResults: []RevisionResult{
- {
- OID: "c60514b6d3d6bf4bec1030f70026e34dfbd69ad5",
- ObjectName: []byte("README.md"),
- },
+ desc: "single file",
+ setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
+ treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "unchanged", Mode: "100644", Content: "unchanged"},
+ {Path: "changed", Mode: "100644", Content: "a"},
+ })
+
+ changedBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("b"))
+ treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "unchanged", Mode: "100644", Content: "unchanged"},
+ {Path: "changed", Mode: "100644", OID: changedBlob},
+ })
+
+ return treeA.Revision(), treeB.Revision(), []RevisionResult{
+ {OID: changedBlob, ObjectName: []byte("changed")},
+ }
},
},
{
- desc: "single file in subtree without recursive",
- leftRevision: "7975be0116940bf2ad4321f79d02a55c5f7779aa",
- rightRevision: "1e292f8fedd741b75372e19097c76d327140c312",
- expectedResults: []RevisionResult{
- {
- OID: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e",
- ObjectName: []byte("files"),
- },
+ desc: "single file in subtree without recursive",
+ setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
+ treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {
+ Path: "unchanged",
+ Mode: "100644",
+ Content: "unchanged",
+ },
+ {
+ Path: "subtree",
+ Mode: "040000",
+ OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "changed", Mode: "100644", Content: "a"},
+ }),
+ },
+ })
+
+ changedSubtree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "changed", Mode: "100644", Content: "b"},
+ })
+ treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {
+ Path: "unchanged",
+ Mode: "100644",
+ Content: "unchanged",
+ },
+ {
+ Path: "subtree",
+ Mode: "040000",
+ OID: changedSubtree,
+ },
+ })
+
+ return treeA.Revision(), treeB.Revision(), []RevisionResult{
+ {OID: changedSubtree, ObjectName: []byte("subtree")},
+ }
},
},
{
- desc: "single file in subtree with recursive",
- leftRevision: "7975be0116940bf2ad4321f79d02a55c5f7779aa",
- rightRevision: "1e292f8fedd741b75372e19097c76d327140c312",
+ desc: "single file in subtree with recursive",
+ setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
+ treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {
+ Path: "unchanged",
+ Mode: "100644",
+ Content: "unchanged",
+ },
+ {
+ Path: "subtree",
+ Mode: "040000",
+ OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "changed", Mode: "100644", Content: "a"},
+ }),
+ },
+ })
+
+ changedBlob := gittest.WriteBlob(t, cfg, repoPath, []byte("b"))
+ treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {
+ Path: "unchanged",
+ Mode: "100644",
+ Content: "unchanged",
+ },
+ {
+ Path: "subtree",
+ Mode: "040000",
+ OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "changed", Mode: "100644", OID: changedBlob},
+ }),
+ },
+ })
+
+ return treeA.Revision(), treeB.Revision(), []RevisionResult{
+ {OID: changedBlob, ObjectName: []byte("subtree/changed")},
+ }
+ },
options: []DiffTreeOption{
DiffTreeWithRecursive(),
},
- expectedResults: []RevisionResult{
- {
- OID: "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
- ObjectName: []byte("files/flat/path/correct/content.txt"),
- },
- },
},
{
- desc: "with submodules",
- leftRevision: "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
- rightRevision: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
- expectedResults: []RevisionResult{
- {
- OID: "efd587ccb47caf5f31fc954edb21f0a713d9ecc3",
- ObjectName: []byte(".gitmodules"),
- },
- {
- OID: "645f6c4c82fd3f5e06f67134450a570b795e55a6",
- ObjectName: []byte("gitlab-grack"),
- },
+ desc: "with submodules",
+ setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
+ submodule := gittest.WriteCommit(t, cfg, repoPath)
+
+ treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: ".gitmodules", Mode: "100644", Content: "a"},
+ })
+
+ changedGitmodules := gittest.WriteBlob(t, cfg, repoPath, []byte("b"))
+ treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: ".gitmodules", Mode: "100644", OID: changedGitmodules},
+ {Path: "submodule", Mode: "160000", OID: submodule},
+ })
+
+ return treeA.Revision(), treeB.Revision(), []RevisionResult{
+ {OID: changedGitmodules, ObjectName: []byte(".gitmodules")},
+ {OID: submodule, ObjectName: []byte("submodule")},
+ }
},
},
{
- desc: "without submodules",
- leftRevision: "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
- rightRevision: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
+ desc: "without submodules",
+ setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
+ submodule := gittest.WriteCommit(t, cfg, repoPath)
+
+ treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: ".gitmodules", Mode: "100644", Content: "a"},
+ })
+
+ changedGitmodules := gittest.WriteBlob(t, cfg, repoPath, []byte("b"))
+ treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: ".gitmodules", Mode: "100644", OID: changedGitmodules},
+ {Path: "submodule", Mode: "160000", OID: submodule},
+ })
+
+ return treeA.Revision(), treeB.Revision(), []RevisionResult{
+ {OID: changedGitmodules, ObjectName: []byte(".gitmodules")},
+ }
+ },
options: []DiffTreeOption{
DiffTreeWithIgnoreSubmodules(),
},
- expectedResults: []RevisionResult{
- {
- OID: "efd587ccb47caf5f31fc954edb21f0a713d9ecc3",
- ObjectName: []byte(".gitmodules"),
- },
- },
},
{
- desc: "with skip function",
- leftRevision: "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
- rightRevision: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
+ desc: "with skip function",
+ setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
+ treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "a", Mode: "100644", Content: "1"},
+ {Path: "b", Mode: "100644", Content: "2"},
+ })
+
+ changedBlobA := gittest.WriteBlob(t, cfg, repoPath, []byte("x"))
+ treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "a", Mode: "100644", OID: changedBlobA},
+ {Path: "b", Mode: "100644", Content: "y"},
+ })
+
+ return treeA.Revision(), treeB.Revision(), []RevisionResult{
+ {OID: changedBlobA, ObjectName: []byte("a")},
+ }
+ },
options: []DiffTreeOption{
DiffTreeWithSkip(func(r *RevisionResult) bool {
- return r.OID == "efd587ccb47caf5f31fc954edb21f0a713d9ecc3"
+ return bytes.Equal(r.ObjectName, []byte("b"))
}),
},
- expectedResults: []RevisionResult{
- {
- OID: "645f6c4c82fd3f5e06f67134450a570b795e55a6",
- ObjectName: []byte("gitlab-grack"),
- },
- },
},
{
- desc: "invalid revision",
- leftRevision: "refs/heads/master",
- rightRevision: "refs/heads/does-not-exist",
+ desc: "invalid revision",
+ setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
+ gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"))
+ return "refs/heads/main", "refs/heads/does-not-exist", nil
+ },
expectedErr: errors.New("diff-tree pipeline command: exit status 128, stderr: " +
"\"fatal: ambiguous argument 'refs/heads/does-not-exist': unknown revision or path not in the working tree.\\n" +
"Use '--' to separate paths from revisions, like this:\\n" +
@@ -123,7 +206,14 @@ func TestDiffTree(t *testing.T) {
},
} {
t.Run(tc.desc, func(t *testing.T) {
- it := DiffTree(ctx, repo, tc.leftRevision, tc.rightRevision, tc.options...)
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ SkipCreationViaService: true,
+ })
+ repo := localrepo.NewTestRepo(t, cfg, repoProto)
+
+ leftRevision, rightRevision, expectedResults := tc.setup(t, repoPath)
+
+ it := DiffTree(ctx, repo, leftRevision.String(), rightRevision.String(), tc.options...)
var results []RevisionResult
for it.Next() {
@@ -138,7 +228,7 @@ func TestDiffTree(t *testing.T) {
}
require.Equal(t, tc.expectedErr, err)
- require.Equal(t, tc.expectedResults, results)
+ require.Equal(t, expectedResults, results)
})
}
}
diff --git a/internal/git/gitpipe/ls_tree.go b/internal/git/gitpipe/ls_tree.go
index 5d2ad775f..3c21c1eb0 100644
--- a/internal/git/gitpipe/ls_tree.go
+++ b/internal/git/gitpipe/ls_tree.go
@@ -56,6 +56,14 @@ func LsTree(
go func() {
defer close(resultChan)
+ objectHash, err := repo.ObjectHash(ctx)
+ if err != nil {
+ sendRevisionResult(ctx, resultChan, RevisionResult{
+ err: fmt.Errorf("detecting object hash: %w", err),
+ })
+ return
+ }
+
flags := []git.Option{
git.Flag{Name: "-z"},
}
@@ -80,7 +88,7 @@ func LsTree(
return
}
- parser := lstree.NewParser(cmd, git.ObjectHashSHA1)
+ parser := lstree.NewParser(cmd, objectHash)
for {
entry, err := parser.NextEntry()
if err != nil {
diff --git a/internal/git/gitpipe/ls_tree_test.go b/internal/git/gitpipe/ls_tree_test.go
index 0a90f0fec..e5a7bdccf 100644
--- a/internal/git/gitpipe/ls_tree_test.go
+++ b/internal/git/gitpipe/ls_tree_test.go
@@ -1,5 +1,3 @@
-//go:build !gitaly_test_sha256
-
package gitpipe
import (
@@ -7,6 +5,7 @@ import (
"testing"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
@@ -14,127 +13,161 @@ import (
)
func TestLsTree(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
cfg := testcfg.Build(t)
- repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
- SkipCreationViaService: true,
- Seed: gittest.SeedGitLabTest,
- })
- repo := localrepo.NewTestRepo(t, cfg, repoProto)
-
for _, tc := range []struct {
- desc string
- revision string
- options []LsTreeOption
- expectedResults []RevisionResult
- expectedErr error
+ desc string
+ setup func(t *testing.T, repoPath string) (git.Revision, []RevisionResult)
+ options []LsTreeOption
+ expectedErr error
}{
{
- desc: "initial commit",
- revision: "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863",
- expectedResults: []RevisionResult{
- {OID: "470ad2fcf1e33798f1afc5781d08e60c40f51e7a", ObjectName: []byte(".gitignore")},
- {OID: "50b27c6518be44c42c4d87966ae2481ce895624c", ObjectName: []byte("LICENSE")},
- {OID: "faaf198af3a36dbf41961466703cc1d47c61d051", ObjectName: []byte("README.md")},
+ desc: "initial commit",
+ setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) {
+ blobA := gittest.WriteBlob(t, cfg, repoPath, []byte("a"))
+ blobB := gittest.WriteBlob(t, cfg, repoPath, []byte("b"))
+ blobC := gittest.WriteBlob(t, cfg, repoPath, []byte("c"))
+
+ tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: ".gitignore", Mode: "100644", OID: blobA},
+ {Path: "LICENSE", Mode: "100644", OID: blobB},
+ {Path: "README.md", Mode: "100644", OID: blobC},
+ })
+
+ return tree.Revision(), []RevisionResult{
+ {OID: blobA, ObjectName: []byte(".gitignore")},
+ {OID: blobB, ObjectName: []byte("LICENSE")},
+ {OID: blobC, ObjectName: []byte("README.md")},
+ }
},
},
{
- desc: "includes submodule",
- revision: "cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
- expectedResults: []RevisionResult{
- {OID: "470ad2fcf1e33798f1afc5781d08e60c40f51e7a", ObjectName: []byte(".gitignore")},
- {OID: "fdaada1754989978413d618ee1fb1c0469d6a664", ObjectName: []byte(".gitmodules")},
- {OID: "c1788657b95998a2f177a4f86d68a60f2a80117f", ObjectName: []byte("CONTRIBUTING.md")},
- {OID: "50b27c6518be44c42c4d87966ae2481ce895624c", ObjectName: []byte("LICENSE")},
- {OID: "faaf198af3a36dbf41961466703cc1d47c61d051", ObjectName: []byte("README.md")},
- {OID: "409f37c4f05865e4fb208c771485f211a22c4c2d", ObjectName: []byte("six")},
+ desc: "includes submodule",
+ setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) {
+ blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a"))
+ commit := gittest.WriteCommit(t, cfg, repoPath)
+
+ tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "blob", Mode: "100644", OID: blob},
+ {Path: "submodule", Mode: "160000", OID: commit},
+ })
+
+ return tree.Revision(), []RevisionResult{
+ {OID: blob, ObjectName: []byte("blob")},
+ {OID: commit, ObjectName: []byte("submodule")},
+ }
},
},
{
- desc: "filter blobs only",
- revision: "cfe32cf61b73a0d5e9f13e774abde7ff789b1660",
+ desc: "filter blobs only",
+ setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) {
+ blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a"))
+ commit := gittest.WriteCommit(t, cfg, repoPath)
+
+ tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {
+ Path: "blob",
+ Mode: "100644",
+ OID: blob,
+ },
+ {
+ Path: "submodule",
+ Mode: "160000",
+ OID: commit,
+ },
+ {
+ Path: "subtree",
+ Mode: "040000",
+ OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "blob-in-subtree", Mode: "100644", Content: "something"},
+ }),
+ },
+ })
+
+ return tree.Revision(), []RevisionResult{
+ {OID: blob, ObjectName: []byte("blob")},
+ }
+ },
options: []LsTreeOption{
LsTreeWithBlobFilter(),
},
- expectedResults: []RevisionResult{
- {OID: "470ad2fcf1e33798f1afc5781d08e60c40f51e7a", ObjectName: []byte(".gitignore")},
- {OID: "fdaada1754989978413d618ee1fb1c0469d6a664", ObjectName: []byte(".gitmodules")},
- {OID: "c1788657b95998a2f177a4f86d68a60f2a80117f", ObjectName: []byte("CONTRIBUTING.md")},
- {OID: "50b27c6518be44c42c4d87966ae2481ce895624c", ObjectName: []byte("LICENSE")},
- {OID: "faaf198af3a36dbf41961466703cc1d47c61d051", ObjectName: []byte("README.md")},
- },
},
{
- desc: "empty tree",
- revision: "7efb185dd22fd5c51ef044795d62b7847900c341",
+ desc: "empty tree",
+ setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) {
+ return gittest.DefaultObjectHash.EmptyTreeOID.Revision(), nil
+ },
},
{
- desc: "non-recursive",
- revision: "913c66a37b4a45b9769037c55c2d238bd0942d2e",
- expectedResults: []RevisionResult{
- {OID: "fd90a3d2d21d6b4f9bec2c33fb7f49780c55f0d2", ObjectName: []byte(".DS_Store")},
- {OID: "470ad2fcf1e33798f1afc5781d08e60c40f51e7a", ObjectName: []byte(".gitignore")},
- {OID: "fdaada1754989978413d618ee1fb1c0469d6a664", ObjectName: []byte(".gitmodules")},
- {OID: "c74175afd117781cbc983664339a0f599b5bb34e", ObjectName: []byte("CHANGELOG")},
- {OID: "c1788657b95998a2f177a4f86d68a60f2a80117f", ObjectName: []byte("CONTRIBUTING.md")},
- {OID: "50b27c6518be44c42c4d87966ae2481ce895624c", ObjectName: []byte("LICENSE")},
- {OID: "95d9f0a5e7bb054e9dd3975589b8dfc689e20e88", ObjectName: []byte("MAINTENANCE.md")},
- {OID: "bf757025c40c62e6ffa6f11d3819c769a76dbe09", ObjectName: []byte("PROCESS.md")},
- {OID: "faaf198af3a36dbf41961466703cc1d47c61d051", ObjectName: []byte("README.md")},
- {OID: "998707b421c89bd9a3063333f9f728ef3e43d101", ObjectName: []byte("VERSION")},
- {OID: "3c122d2b7830eca25235131070602575cf8b41a1", ObjectName: []byte("encoding")},
- {OID: "ab746f8ad0b84b147290041dc13cc9c7adc52930", ObjectName: []byte("files")},
- {OID: "409f37c4f05865e4fb208c771485f211a22c4c2d", ObjectName: []byte("six")},
+ desc: "non-recursive",
+ setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) {
+ blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a"))
+ subtree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "blob-in-subtree", Mode: "100644", Content: "something"},
+ })
+
+ tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "blob", Mode: "100644", OID: blob},
+ {Path: "subtree", Mode: "040000", OID: subtree},
+ })
+
+ return tree.Revision(), []RevisionResult{
+ {OID: blob, ObjectName: []byte("blob")},
+ {OID: subtree, ObjectName: []byte("subtree")},
+ }
},
},
{
- desc: "recursive",
- revision: "913c66a37b4a45b9769037c55c2d238bd0942d2e",
+ desc: "recursive",
+ setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) {
+ blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a"))
+ blobInSubtree := gittest.WriteBlob(t, cfg, repoPath, []byte("b"))
+
+ tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {
+ Path: "blob",
+ Mode: "100644",
+ OID: blob,
+ },
+ {
+ Path: "subtree",
+ Mode: "040000",
+ OID: gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "blob-in-subtree", Mode: "100644", OID: blobInSubtree},
+ }),
+ },
+ })
+
+ return tree.Revision(), []RevisionResult{
+ {OID: blob, ObjectName: []byte("blob")},
+ {OID: blobInSubtree, ObjectName: []byte("subtree/blob-in-subtree")},
+ }
+ },
options: []LsTreeOption{
LsTreeWithRecursive(),
},
- expectedResults: []RevisionResult{
- {OID: "fd90a3d2d21d6b4f9bec2c33fb7f49780c55f0d2", ObjectName: []byte(".DS_Store")},
- {OID: "470ad2fcf1e33798f1afc5781d08e60c40f51e7a", ObjectName: []byte(".gitignore")},
- {OID: "fdaada1754989978413d618ee1fb1c0469d6a664", ObjectName: []byte(".gitmodules")},
- {OID: "c74175afd117781cbc983664339a0f599b5bb34e", ObjectName: []byte("CHANGELOG")},
- {OID: "c1788657b95998a2f177a4f86d68a60f2a80117f", ObjectName: []byte("CONTRIBUTING.md")},
- {OID: "50b27c6518be44c42c4d87966ae2481ce895624c", ObjectName: []byte("LICENSE")},
- {OID: "95d9f0a5e7bb054e9dd3975589b8dfc689e20e88", ObjectName: []byte("MAINTENANCE.md")},
- {OID: "bf757025c40c62e6ffa6f11d3819c769a76dbe09", ObjectName: []byte("PROCESS.md")},
- {OID: "faaf198af3a36dbf41961466703cc1d47c61d051", ObjectName: []byte("README.md")},
- {OID: "998707b421c89bd9a3063333f9f728ef3e43d101", ObjectName: []byte("VERSION")},
- {OID: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", ObjectName: []byte("encoding/feature-1.txt")},
- {OID: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", ObjectName: []byte("encoding/feature-2.txt")},
- {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("encoding/hotfix-1.txt")},
- {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("encoding/hotfix-2.txt")},
- {OID: "570f8e1dfe8149c1d17002712310d43dfeb43159", ObjectName: []byte("encoding/russian.rb")},
- {OID: "7a17968582c21c9153ec24c6a9d5f33592ad9103", ObjectName: []byte("encoding/test.txt")},
- {OID: "f3064a3aa9c14277483f690250072e987e2c8356", ObjectName: []byte("encoding/\343\203\206\343\202\271\343\203\210.txt")},
- {OID: "3a26c18b02e843b459732e7ade7ab9a154a1002b", ObjectName: []byte("encoding/\343\203\206\343\202\271\343\203\210.xls")},
- {OID: "60d7a906c2fd9e4509aeb1187b98d0ea7ce827c9", ObjectName: []byte("files/.DS_Store")},
- {OID: "c84b9e90e4bee2666f5cb3688690d9824d88f3ee", ObjectName: []byte("files/html/500.html")},
- {OID: "4a96572d570108366da2cf5aa8213f69b591a2a3", ObjectName: []byte("files/images/logo-black.png")},
- {OID: "bc2ef601a538d69ef99d5bdafa605e63f902e8e4", ObjectName: []byte("files/images/logo-white.png")},
- {OID: "4a393dbfe81113d35d9aedeb5c76f763190c1b2f", ObjectName: []byte("files/js/application.js")},
- {OID: "5f53439ca4b009096571d3c8bc3d09d30e7431b3", ObjectName: []byte("files/js/commit.js.coffee")},
- {OID: "3da5c4ddbaf17d37aea52c485d8bb85b07d77816", ObjectName: []byte("files/markdown/ruby-style-guide.md")},
- {OID: "e2fbafb389911ef68e4da2da7da917f6acb9e86a", ObjectName: []byte("files/ruby/popen.rb")},
- {OID: "d18fc8bf2cecbe21bbbd5da692eaf83e32c48638", ObjectName: []byte("files/ruby/regex.rb")},
- {OID: "6ee41e85cc9bf33c10b690df09ca735b22f3790f", ObjectName: []byte("files/ruby/version_info.rb")},
- {OID: "409f37c4f05865e4fb208c771485f211a22c4c2d", ObjectName: []byte("six")},
- },
},
{
- desc: "invalid revision",
- revision: "refs/heads/does-not-exist",
+ desc: "invalid revision",
+ setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) {
+ return "refs/heads/does-not-exist", nil
+ },
expectedErr: errors.New("ls-tree pipeline command: exit status 128, stderr: " +
"\"fatal: Not a valid object name refs/heads/does-not-exist\\n\""),
},
} {
t.Run(tc.desc, func(t *testing.T) {
- it := LsTree(ctx, repo, tc.revision, tc.options...)
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ SkipCreationViaService: true,
+ })
+ repo := localrepo.NewTestRepo(t, cfg, repoProto)
+
+ revision, expectedResults := tc.setup(t, repoPath)
+
+ it := LsTree(ctx, repo, revision.String(), tc.options...)
var results []RevisionResult
for it.Next() {
@@ -149,7 +182,7 @@ func TestLsTree(t *testing.T) {
}
require.Equal(t, tc.expectedErr, err)
- require.Equal(t, tc.expectedResults, results)
+ require.Equal(t, expectedResults, results)
})
}
}
diff --git a/internal/git/gitpipe/pipeline_test.go b/internal/git/gitpipe/pipeline_test.go
index 797d1fced..2af0f0496 100644
--- a/internal/git/gitpipe/pipeline_test.go
+++ b/internal/git/gitpipe/pipeline_test.go
@@ -1,5 +1,3 @@
-//go:build !gitaly_test_sha256
-
package gitpipe
import (
@@ -19,15 +17,31 @@ import (
)
func TestPipeline_revlist(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
cfg := testcfg.Build(t)
- repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
SkipCreationViaService: true,
- Seed: gittest.SeedGitLabTest,
})
repo := localrepo.NewTestRepo(t, cfg, repoProto)
+ blobA := gittest.WriteBlob(t, cfg, repoPath, []byte("blob a"))
+ blobB := gittest.WriteBlob(t, cfg, repoPath, []byte("b"))
+ blobC := gittest.WriteBlob(t, cfg, repoPath, []byte("longer blob c"))
+
+ subtree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "subblob", Mode: "100644", OID: blobA},
+ })
+ tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "blob", Mode: "100644", OID: blobB},
+ {Path: "subtree", Mode: "040000", OID: subtree},
+ })
+
+ commitA := gittest.WriteCommit(t, cfg, repoPath)
+ commitB := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(commitA), gittest.WithTree(tree), gittest.WithBranch("main"))
+
for _, tc := range []struct {
desc string
revisions []string
@@ -39,79 +53,81 @@ func TestPipeline_revlist(t *testing.T) {
{
desc: "single blob",
revisions: []string{
- lfsPointer1,
+ blobA.String(),
},
revlistOptions: []RevlistOption{
WithObjects(),
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}},
},
},
{
desc: "single blob without objects",
revisions: []string{
- lfsPointer1,
+ blobA.String(),
},
expectedResults: nil,
},
{
desc: "multiple blobs",
revisions: []string{
- lfsPointer1,
- lfsPointer2,
- lfsPointer3,
+ blobA.String(),
+ blobB.String(),
+ blobC.String(),
},
revlistOptions: []RevlistOption{
WithObjects(),
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobC, Type: "blob", Size: 13}}},
},
},
{
desc: "multiple blobs with filter",
revisions: []string{
- lfsPointer1,
- lfsPointer2,
- lfsPointer3,
+ blobA.String(),
+ blobB.String(),
+ blobC.String(),
},
revlistOptions: []RevlistOption{
WithObjects(),
WithSkipRevlistResult(func(r *RevisionResult) bool {
- return r.OID != lfsPointer2
+ return r.OID != blobB
}),
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}},
},
},
{
desc: "tree",
revisions: []string{
- "b95c0fad32f4361845f91d9ce4c1721b52b82793",
+ tree.String(),
},
revlistOptions: []RevlistOption{
WithObjects(),
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}}, ObjectName: []byte("branch-test.txt")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: tree, Type: "tree", Size: hashDependentObjectSize(66, 90)}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}, ObjectName: []byte("blob")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: subtree, Type: "tree", Size: hashDependentObjectSize(35, 47)}}, ObjectName: []byte("subtree")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}, ObjectName: []byte("subtree/subblob")},
},
},
{
desc: "tree without objects",
revisions: []string{
- "b95c0fad32f4361845f91d9ce4c1721b52b82793",
+ tree.String(),
},
expectedResults: nil,
},
{
desc: "tree with blob filter",
revisions: []string{
- "b95c0fad32f4361845f91d9ce4c1721b52b82793",
+ tree.String(),
},
revlistOptions: []RevlistOption{
WithObjects(),
@@ -122,37 +138,35 @@ func TestPipeline_revlist(t *testing.T) {
}),
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}}, ObjectName: []byte("branch-test.txt")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}, ObjectName: []byte("blob")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}, ObjectName: []byte("subtree/subblob")},
},
},
{
desc: "revision range",
revisions: []string{
- "^master~",
- "master",
+ "^" + commitB.String() + "~",
+ commitB.String(),
},
revlistOptions: []RevlistOption{
WithObjects(),
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "1e292f8fedd741b75372e19097c76d327140c312", Type: "commit", Size: 388}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "07f8147e8e73aab6c935c296e8cdc5194dee729b", Type: "tree", Size: 780}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", Type: "tree", Size: 258}}, ObjectName: []byte("files")},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "2132d150328bd9334cc4e62a16a5d998a7e399b9", Type: "tree", Size: 31}}, ObjectName: []byte("files/flat")},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", Type: "tree", Size: 34}}, ObjectName: []byte("files/flat/path")},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "ea7249055466085d0a6c69951908ef47757e92f4", Type: "tree", Size: 39}}, ObjectName: []byte("files/flat/path/correct")},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", Type: "commit", Size: 326}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: commitB, Type: "commit", Size: hashDependentObjectSize(225, 273)}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: tree, Type: "tree", Size: hashDependentObjectSize(66, 90)}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}, ObjectName: []byte("blob")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: subtree, Type: "tree", Size: hashDependentObjectSize(35, 47)}}, ObjectName: []byte("subtree")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}, ObjectName: []byte("subtree/subblob")},
},
},
{
desc: "revision range without objects",
revisions: []string{
- "^master~",
- "master",
+ "^" + commitB.String() + "~",
+ commitB.String(),
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "1e292f8fedd741b75372e19097c76d327140c312", Type: "commit", Size: 388}}},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", Type: "commit", Size: 326}}},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: commitB, Type: "commit", Size: hashDependentObjectSize(225, 273)}}},
},
},
{
@@ -163,20 +177,19 @@ func TestPipeline_revlist(t *testing.T) {
revlistOptions: []RevlistOption{
WithObjects(),
WithSkipRevlistResult(func(r *RevisionResult) bool {
- // Let through two LFS pointers and a tree.
- return r.OID != "b95c0fad32f4361845f91d9ce4c1721b52b82793" &&
- r.OID != lfsPointer1 && r.OID != lfsPointer2
+ // Let through two blobs and a tree.
+ return r.OID != tree && r.OID != blobA && r.OID != blobB
}),
},
catfileInfoOptions: []CatfileInfoOption{
WithSkipCatfileInfoResult(func(objectInfo *catfile.ObjectInfo) bool {
- // Only let through blobs, so only the two LFS pointers remain.
+ // Only let through blobs, so only the two blobs remain.
return objectInfo.Type != "blob"
}),
},
expectedResults: []CatfileObjectResult{
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, ObjectName: []byte("files/lfs/lfs_object.iso")},
- {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, ObjectName: []byte("another.lfs")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobB, Type: "blob", Size: 1}}, ObjectName: []byte("blob")},
+ {Object: &catfile.Object{ObjectInfo: catfile.ObjectInfo{Oid: blobA, Type: "blob", Size: 6}}, ObjectName: []byte("subtree/subblob")},
},
},
{
@@ -192,9 +205,9 @@ func TestPipeline_revlist(t *testing.T) {
{
desc: "mixed valid and invalid revision",
revisions: []string{
- lfsPointer1,
+ blobA.String(),
"doesnotexist",
- lfsPointer2,
+ blobB.String(),
},
expectedErr: errors.New("rev-list pipeline command: exit status 128, stderr: " +
"\"fatal: ambiguous argument 'doesnotexist': unknown revision or path not in the working tree.\\n" +
@@ -309,7 +322,7 @@ func TestPipeline_revlist(t *testing.T) {
_, err := io.Copy(io.Discard, catfileObjectIter.Result())
require.NoError(t, err)
- if i == 3 {
+ if i == 1 {
cancel()
}
}
@@ -368,20 +381,28 @@ func TestPipeline_revlist(t *testing.T) {
// We could in theory assert the exact amount of objects, but this would make it
// harder than necessary to change the test repo's contents.
- require.Greater(t, i, 1000)
+ require.Equal(t, i, 7)
})
}
func TestPipeline_forEachRef(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
cfg := testcfg.Build(t)
- repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
SkipCreationViaService: true,
- Seed: gittest.SeedGitLabTest,
})
repo := localrepo.NewTestRepo(t, cfg, repoProto)
+ keepaliveCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithReference("refs/keep-alive/a"), gittest.WithMessage("keepalive"))
+ mainCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithMessage("main"))
+ featureCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("feature"), gittest.WithMessage("feature"))
+ tag := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", mainCommit.Revision(), gittest.WriteTagConfig{
+ Message: "annotated",
+ })
+
catfileCache := catfile.NewCache(cfg)
defer catfileCache.Stop()
@@ -406,6 +427,22 @@ func TestPipeline_forEachRef(t *testing.T) {
content []byte
}
+ expectedRefs := map[git.ReferenceName]object{
+ "refs/keep-alive/a": {oid: keepaliveCommit, content: []byte("xx")},
+ "refs/heads/main": {oid: mainCommit, content: []byte("xx")},
+ "refs/heads/feature": {oid: featureCommit, content: []byte("xx")},
+ "refs/tags/v1.0.0": {oid: tag, content: []byte("xx")},
+ }
+ for expectedRef, expectedObject := range expectedRefs {
+ content, err := repo.ReadObject(ctx, expectedObject.oid)
+ require.NoError(t, err)
+
+ expectedRefs[expectedRef] = object{
+ oid: expectedObject.oid,
+ content: content,
+ }
+ }
+
objectsByRef := make(map[git.ReferenceName]object)
for catfileObjectIter.Next() {
result := catfileObjectIter.Result()
@@ -420,24 +457,5 @@ func TestPipeline_forEachRef(t *testing.T) {
}
}
require.NoError(t, catfileObjectIter.Err())
- require.Greater(t, len(objectsByRef), 90)
-
- // We certainly don't want to hard-code all the references, so we just cross-check with the
- // localrepo implementation to verify that both return the same data.
- refs, err := repo.GetReferences(ctx)
- require.NoError(t, err)
- require.Equal(t, len(refs), len(objectsByRef))
-
- expectedObjectsByRef := make(map[git.ReferenceName]object)
- for _, ref := range refs {
- oid := git.ObjectID(ref.Target)
- content, err := repo.ReadObject(ctx, oid)
- require.NoError(t, err)
-
- expectedObjectsByRef[ref.Name] = object{
- oid: oid,
- content: content,
- }
- }
- require.Equal(t, expectedObjectsByRef, objectsByRef)
+ require.Equal(t, expectedRefs, objectsByRef)
}
diff --git a/internal/git/gitpipe/revision_test.go b/internal/git/gitpipe/revision_test.go
index 7e740c247..723f1316b 100644
--- a/internal/git/gitpipe/revision_test.go
+++ b/internal/git/gitpipe/revision_test.go
@@ -1,8 +1,7 @@
-//go:build !gitaly_test_sha256
-
package gitpipe
import (
+ "bytes"
"context"
"errors"
"testing"
@@ -10,7 +9,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config"
@@ -19,15 +17,63 @@ import (
)
func TestRevlist(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
cfg := testcfg.Build(t)
- repoProto, _ := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
SkipCreationViaService: true,
- Seed: gittest.SeedGitLabTest,
})
repo := localrepo.NewTestRepo(t, cfg, repoProto)
+ blobA := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("a"), 133))
+ blobB := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("b"), 127))
+ blobC := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("c"), 127))
+ blobD := gittest.WriteBlob(t, cfg, repoPath, bytes.Repeat([]byte("d"), 129))
+
+ blob := gittest.WriteBlob(t, cfg, repoPath, []byte("a"))
+ subblob := gittest.WriteBlob(t, cfg, repoPath, []byte("larger blob"))
+
+ treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "branch-test.txt", Mode: "100644", OID: blob},
+ })
+ commitA := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithTree(treeA),
+ gittest.WithCommitterDate(time.Date(2000, 1, 1, 1, 1, 1, 1, time.UTC)),
+ )
+
+ subtree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "subblob", Mode: "100644", OID: subblob},
+ })
+ treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "branch-test.txt", Mode: "100644", OID: blob},
+ {Path: "subtree", Mode: "040000", OID: subtree},
+ })
+ commitB := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithParents(commitA),
+ gittest.WithTree(treeB),
+ gittest.WithCommitterDate(time.Date(1999, 1, 1, 1, 1, 1, 1, time.UTC)),
+ gittest.WithAuthorName("custom author"),
+ )
+
+ commitBParent := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithParents(commitB),
+ gittest.WithTree(treeB),
+ gittest.WithCommitterDate(time.Date(2001, 1, 1, 1, 1, 1, 1, time.UTC)),
+ )
+ commitAParent := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithParents(commitA),
+ gittest.WithTree(treeA),
+ gittest.WithCommitterDate(time.Date(2001, 1, 1, 1, 1, 1, 1, time.UTC)),
+ )
+
+ mergeCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(commitAParent, commitBParent))
+
+ tag := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", mergeCommit.Revision(), gittest.WriteTagConfig{
+ Message: "annotated tag",
+ })
+
for _, tc := range []struct {
desc string
revisions []string
@@ -38,150 +84,146 @@ func TestRevlist(t *testing.T) {
{
desc: "single blob",
revisions: []string{
- lfsPointer1,
+ blobA.String(),
},
options: []RevlistOption{
WithObjects(),
},
expectedResults: []RevisionResult{
- {OID: lfsPointer1},
+ {OID: blobA},
},
},
{
desc: "multiple blobs",
revisions: []string{
- lfsPointer1,
- lfsPointer2,
- lfsPointer3,
- lfsPointer4,
+ blobA.String(),
+ blobB.String(),
+ blobC.String(),
+ blobD.String(),
},
options: []RevlistOption{
WithObjects(),
},
expectedResults: []RevisionResult{
- {OID: lfsPointer1},
- {OID: lfsPointer2},
- {OID: lfsPointer3},
- {OID: lfsPointer4},
+ {OID: blobA},
+ {OID: blobB},
+ {OID: blobC},
+ {OID: blobD},
},
},
{
desc: "multiple blobs without objects",
revisions: []string{
- lfsPointer1,
- lfsPointer2,
- lfsPointer3,
- lfsPointer4,
+ blobA.String(),
+ blobB.String(),
+ blobC.String(),
+ blobD.String(),
},
expectedResults: nil,
},
{
desc: "duplicated blob prints blob once only",
revisions: []string{
- lfsPointer1,
- lfsPointer1,
+ blobA.String(),
+ blobA.String(),
},
options: []RevlistOption{
WithObjects(),
},
expectedResults: []RevisionResult{
- {OID: lfsPointer1},
+ {OID: blobA},
},
},
{
desc: "tree results in object names",
revisions: []string{
- "b95c0fad32f4361845f91d9ce4c1721b52b82793",
+ treeA.String(),
},
options: []RevlistOption{
WithObjects(),
},
expectedResults: []RevisionResult{
- {OID: "b95c0fad32f4361845f91d9ce4c1721b52b82793"},
- {OID: "93e123ac8a3e6a0b600953d7598af629dec7b735", ObjectName: []byte("branch-test.txt")},
+ {OID: treeA},
+ {OID: blob, ObjectName: []byte("branch-test.txt")},
},
},
{
desc: "tree without objects returns nothing",
revisions: []string{
- "b95c0fad32f4361845f91d9ce4c1721b52b82793",
+ treeA.String(),
},
expectedResults: nil,
},
{
desc: "revision without disabled walk",
revisions: []string{
- "refs/heads/master",
+ commitB.String(),
},
options: []RevlistOption{
WithDisabledWalk(),
},
expectedResults: []RevisionResult{
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
+ {OID: commitB},
},
},
{
desc: "revision range",
revisions: []string{
- "^refs/heads/master~",
- "refs/heads/master",
+ "^" + commitB.String() + "~",
+ commitB.String(),
},
options: []RevlistOption{
WithObjects(),
},
expectedResults: []RevisionResult{
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
- {OID: "07f8147e8e73aab6c935c296e8cdc5194dee729b"},
- {OID: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", ObjectName: []byte("files")},
- {OID: "2132d150328bd9334cc4e62a16a5d998a7e399b9", ObjectName: []byte("files/flat")},
- {OID: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", ObjectName: []byte("files/flat/path")},
- {OID: "ea7249055466085d0a6c69951908ef47757e92f4", ObjectName: []byte("files/flat/path/correct")},
- {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"},
+ {OID: commitB},
+ {OID: treeB},
+ {OID: subtree, ObjectName: []byte("subtree")},
+ {OID: subblob, ObjectName: []byte("subtree/subblob")},
},
},
{
desc: "revision range without objects",
revisions: []string{
- "^refs/heads/master~",
- "refs/heads/master",
+ "^" + commitB.String() + "~",
+ commitB.String(),
},
expectedResults: []RevisionResult{
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
- {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"},
+ {OID: commitB},
},
},
{
desc: "revision range without objects with at most one parent",
revisions: []string{
- "^refs/heads/master~",
- "refs/heads/master",
+ mergeCommit.String(),
},
options: []RevlistOption{
WithMaxParents(1),
},
expectedResults: []RevisionResult{
- {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"},
+ {OID: commitAParent},
+ {OID: commitBParent},
+ {OID: commitA},
+ {OID: commitB},
},
},
{
desc: "reverse revision range without objects",
revisions: []string{
- "^refs/heads/master~",
- "refs/heads/master",
+ commitB.String(),
},
options: []RevlistOption{
WithReverse(),
},
expectedResults: []RevisionResult{
- {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"},
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
+ {OID: commitA},
+ {OID: commitB},
},
},
{
desc: "reverse revision range with objects",
revisions: []string{
- "^refs/heads/master~",
- "refs/heads/master",
+ commitB.String(),
},
options: []RevlistOption{
WithReverse(),
@@ -190,110 +232,86 @@ func TestRevlist(t *testing.T) {
expectedResults: []RevisionResult{
// Note that only commits are listed in reverse,
// their referenced objects stay in the same order.
- {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"},
- {OID: "07f8147e8e73aab6c935c296e8cdc5194dee729b"},
- {OID: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", ObjectName: []byte("files")},
- {OID: "2132d150328bd9334cc4e62a16a5d998a7e399b9", ObjectName: []byte("files/flat")},
- {OID: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", ObjectName: []byte("files/flat/path")},
- {OID: "ea7249055466085d0a6c69951908ef47757e92f4", ObjectName: []byte("files/flat/path/correct")},
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
+ {OID: commitA},
+ {OID: treeA},
+ {OID: blob, ObjectName: []byte("branch-test.txt")},
+ {OID: commitB},
+ {OID: treeB},
+ {OID: subtree, ObjectName: []byte("subtree")},
+ {OID: subblob, ObjectName: []byte("subtree/subblob")},
},
},
{
desc: "revision range with topo order",
revisions: []string{
- // This is one of the smaller examples I've found which reproduces
- // different sorting orders between topo- and date-sorting. Expected
- // results contain the same object for this and the next test case,
- // but ordering is different.
- "master",
- "^master~5",
- "flat-path",
+ mergeCommit.String(),
},
options: []RevlistOption{
WithOrder(OrderTopo),
},
expectedResults: []RevisionResult{
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
- {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"},
- {OID: "7975be0116940bf2ad4321f79d02a55c5f7779aa"},
- {OID: "c84ff944ff4529a70788a5e9003c2b7feae29047"},
- {OID: "60ecb67744cb56576c30214ff52294f8ce2def98"},
- {OID: "55bc176024cfa3baaceb71db584c7e5df900ea65"},
- {OID: "e63f41fe459e62e1228fcef60d7189127aeba95a"},
- {OID: "4a24d82dbca5c11c61556f3b35ca472b7463187e"},
- {OID: "b83d6e391c22777fca1ed3012fce84f633d7fed0"},
- {OID: "498214de67004b1da3d820901307bed2a68a8ef6"},
- // The following commit is sorted differently in the next testcase.
- {OID: "ce369011c189f62c815f5971d096b26759bab0d1"},
+ // Note that the order here is different from the order in the next
+ // testcase, where we use date-order.
+ {OID: mergeCommit},
+ {OID: commitBParent},
+ {OID: commitB},
+ {OID: commitAParent},
+ {OID: commitA},
},
},
{
desc: "revision range with date order",
revisions: []string{
- "master",
- "^master~5",
- "flat-path",
+ mergeCommit.String(),
},
options: []RevlistOption{
WithOrder(OrderDate),
},
expectedResults: []RevisionResult{
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
- {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"},
- {OID: "7975be0116940bf2ad4321f79d02a55c5f7779aa"},
- {OID: "c84ff944ff4529a70788a5e9003c2b7feae29047"},
- {OID: "60ecb67744cb56576c30214ff52294f8ce2def98"},
- {OID: "55bc176024cfa3baaceb71db584c7e5df900ea65"},
- // The following commit is sorted differently in the previous
- // testcase.
- {OID: "ce369011c189f62c815f5971d096b26759bab0d1"},
- {OID: "e63f41fe459e62e1228fcef60d7189127aeba95a"},
- {OID: "4a24d82dbca5c11c61556f3b35ca472b7463187e"},
- {OID: "b83d6e391c22777fca1ed3012fce84f633d7fed0"},
- {OID: "498214de67004b1da3d820901307bed2a68a8ef6"},
+ {OID: mergeCommit},
+ {OID: commitAParent},
+ {OID: commitBParent},
+ {OID: commitB},
+ {OID: commitA},
},
},
{
desc: "revision range with dates",
revisions: []string{
- "refs/heads/master",
+ mergeCommit.String(),
},
options: []RevlistOption{
- WithBefore(time.Date(2016, 6, 30, 18, 30, 0, 0, time.UTC)),
- WithAfter(time.Date(2016, 6, 30, 18, 28, 0, 0, time.UTC)),
+ WithBefore(time.Date(2000, 12, 1, 1, 1, 1, 1, time.UTC)),
+ WithAfter(time.Date(1999, 12, 1, 1, 1, 1, 1, time.UTC)),
},
expectedResults: []RevisionResult{
- {OID: "6907208d755b60ebeacb2e9dfea74c92c3449a1f"},
- {OID: "c347ca2e140aa667b968e51ed0ffe055501fe4f4"},
+ {OID: commitA},
},
},
{
desc: "revision range with author",
revisions: []string{
- "refs/heads/master",
+ mergeCommit.String(),
},
options: []RevlistOption{
- WithAuthor([]byte("Sytse")),
+ WithAuthor([]byte("custom author")),
},
expectedResults: []RevisionResult{
- {OID: "e56497bb5f03a90a51293fc6d516788730953899"},
+ {OID: commitB},
},
},
{
desc: "first parent chain",
revisions: []string{
- "master",
- "^master~4",
+ mergeCommit.String(),
},
options: []RevlistOption{
WithFirstParent(),
},
expectedResults: []RevisionResult{
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
- {OID: "7975be0116940bf2ad4321f79d02a55c5f7779aa"},
- {OID: "60ecb67744cb56576c30214ff52294f8ce2def98"},
- {OID: "e63f41fe459e62e1228fcef60d7189127aeba95a"},
+ {OID: mergeCommit},
+ {OID: commitAParent},
+ {OID: commitA},
},
},
{
@@ -305,22 +323,16 @@ func TestRevlist(t *testing.T) {
// twice, once without and once with limit.
desc: "tree with multiple blobs without limit",
revisions: []string{
- "79d5f98270ad677c86a7e1ab2baa922958565135",
+ treeB.String(),
},
options: []RevlistOption{
WithObjects(),
},
expectedResults: []RevisionResult{
- {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"},
- {OID: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", ObjectName: []byte("feature-1.txt")},
- {OID: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", ObjectName: []byte("feature-2.txt")},
- {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")},
- {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")},
- {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")},
- {OID: "570f8e1dfe8149c1d17002712310d43dfeb43159", ObjectName: []byte("russian.rb")},
- {OID: "7a17968582c21c9153ec24c6a9d5f33592ad9103", ObjectName: []byte("test.txt")},
- {OID: "f3064a3aa9c14277483f690250072e987e2c8356", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt")},
- {OID: "3a26c18b02e843b459732e7ade7ab9a154a1002b", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.xls")},
+ {OID: treeB},
+ {OID: blob, ObjectName: []byte("branch-test.txt")},
+ {OID: subtree, ObjectName: []byte("subtree")},
+ {OID: subblob, ObjectName: []byte("subtree/subblob")},
},
},
{
@@ -328,38 +340,30 @@ func TestRevlist(t *testing.T) {
// get less blobs as result.
desc: "tree with multiple blobs with limit",
revisions: []string{
- "79d5f98270ad677c86a7e1ab2baa922958565135",
+ treeB.String(),
},
options: []RevlistOption{
WithObjects(),
- WithBlobLimit(10),
+ WithBlobLimit(5),
},
expectedResults: []RevisionResult{
- {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"},
- {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")},
- {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")},
- {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")},
+ {OID: treeB},
+ {OID: blob, ObjectName: []byte("branch-test.txt")},
+ {OID: subtree, ObjectName: []byte("subtree")},
},
},
{
desc: "tree with blob object type filter",
revisions: []string{
- "79d5f98270ad677c86a7e1ab2baa922958565135",
+ treeB.String(),
},
options: []RevlistOption{
WithObjects(),
WithObjectTypeFilter(ObjectTypeBlob),
},
expectedResults: []RevisionResult{
- {OID: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", ObjectName: []byte("feature-1.txt")},
- {OID: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", ObjectName: []byte("feature-2.txt")},
- {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")},
- {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")},
- {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")},
- {OID: "570f8e1dfe8149c1d17002712310d43dfeb43159", ObjectName: []byte("russian.rb")},
- {OID: "7a17968582c21c9153ec24c6a9d5f33592ad9103", ObjectName: []byte("test.txt")},
- {OID: "f3064a3aa9c14277483f690250072e987e2c8356", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt")},
- {OID: "3a26c18b02e843b459732e7ade7ab9a154a1002b", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.xls")},
+ {OID: blob, ObjectName: []byte("branch-test.txt")},
+ {OID: subblob, ObjectName: []byte("subtree/subblob")},
},
},
{
@@ -372,53 +376,48 @@ func TestRevlist(t *testing.T) {
WithObjectTypeFilter(ObjectTypeTag),
},
expectedResults: []RevisionResult{
- {OID: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", ObjectName: []byte("v1.0.0")},
- {OID: "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", ObjectName: []byte("v1.1.0")},
- {OID: "8f03acbcd11c53d9c9468078f32a2622005a4841", ObjectName: []byte("v1.1.1")},
+ {OID: tag, ObjectName: []byte("v1.0.0")},
},
},
{
- desc: "tree with commit object type filter",
+ desc: "tree with tree object type filter",
revisions: []string{
- "79d5f98270ad677c86a7e1ab2baa922958565135",
+ commitA.String(),
},
options: []RevlistOption{
WithObjects(),
WithObjectTypeFilter(ObjectTypeTree),
},
expectedResults: []RevisionResult{
- {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"},
+ {OID: treeA},
},
},
{
desc: "tree with commit object type filter",
revisions: []string{
- "^refs/heads/master~",
- "refs/heads/master",
+ commitB.String(),
},
options: []RevlistOption{
WithObjects(),
WithObjectTypeFilter(ObjectTypeCommit),
},
expectedResults: []RevisionResult{
- {OID: "1e292f8fedd741b75372e19097c76d327140c312"},
- {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"},
+ {OID: commitB},
+ {OID: commitA},
},
},
{
desc: "tree with object type and blob size filter",
revisions: []string{
- "79d5f98270ad677c86a7e1ab2baa922958565135",
+ mergeCommit.String(),
},
options: []RevlistOption{
WithObjects(),
- WithBlobLimit(10),
+ WithBlobLimit(5),
WithObjectTypeFilter(ObjectTypeBlob),
},
expectedResults: []RevisionResult{
- {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")},
- {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")},
- {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")},
+ {OID: blob, ObjectName: []byte("branch-test.txt")},
},
},
{
@@ -434,7 +433,7 @@ func TestRevlist(t *testing.T) {
{
desc: "mixed valid and invalid revision",
revisions: []string{
- lfsPointer1,
+ blobA.String(),
"refs/heads/does-not-exist",
},
expectedErr: errors.New("rev-list pipeline command: exit status 128, stderr: " +
@@ -445,11 +444,10 @@ func TestRevlist(t *testing.T) {
{
desc: "skip everything",
revisions: []string{
- "79d5f98270ad677c86a7e1ab2baa922958565135",
+ mergeCommit.String(),
},
options: []RevlistOption{
WithObjects(),
- WithBlobLimit(10),
WithObjectTypeFilter(ObjectTypeBlob),
WithSkipRevlistResult(func(*RevisionResult) bool { return true }),
},
@@ -457,36 +455,32 @@ func TestRevlist(t *testing.T) {
{
desc: "skip nothing",
revisions: []string{
- "79d5f98270ad677c86a7e1ab2baa922958565135",
+ mergeCommit.String(),
},
options: []RevlistOption{
WithObjects(),
- WithBlobLimit(10),
WithObjectTypeFilter(ObjectTypeBlob),
WithSkipRevlistResult(func(*RevisionResult) bool { return false }),
},
expectedResults: []RevisionResult{
- {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")},
- {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")},
- {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")},
+ {OID: blob, ObjectName: []byte("branch-test.txt")},
+ {OID: subblob, ObjectName: []byte("subtree/subblob")},
},
},
{
desc: "skip one",
revisions: []string{
- "79d5f98270ad677c86a7e1ab2baa922958565135",
+ mergeCommit.String(),
},
options: []RevlistOption{
WithObjects(),
- WithBlobLimit(10),
WithObjectTypeFilter(ObjectTypeBlob),
WithSkipRevlistResult(func(r *RevisionResult) bool {
- return string(r.ObjectName) == "hotfix-2.txt"
+ return bytes.Equal(r.ObjectName, []byte("branch-test.txt"))
}),
},
expectedResults: []RevisionResult{
- {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")},
- {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")},
+ {OID: subblob, ObjectName: []byte("subtree/subblob")},
},
},
} {
@@ -513,12 +507,12 @@ func TestRevlist(t *testing.T) {
t.Run("context cancellation", func(t *testing.T) {
ctx, cancel := context.WithCancel(testhelper.Context(t))
- it := Revlist(ctx, repo, []string{"refs/heads/master"})
+ it := Revlist(ctx, repo, []string{mergeCommit.String()})
require.True(t, it.Next())
require.NoError(t, it.Err())
require.Equal(t, RevisionResult{
- OID: "1e292f8fedd741b75372e19097c76d327140c312",
+ OID: mergeCommit,
}, it.Result())
cancel()
@@ -532,6 +526,8 @@ func TestRevlist(t *testing.T) {
}
func TestForEachRef(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
readRefs := func(t *testing.T, repo *localrepo.Repo, patterns []string, opts ...ForEachRefOption) []RevisionResult {
@@ -546,55 +542,54 @@ func TestForEachRef(t *testing.T) {
return results
}
- cfg, repoProto, _ := testcfg.BuildWithRepo(t)
+ cfg := testcfg.Build(t)
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ SkipCreationViaService: true,
+ })
repo := localrepo.NewTestRepo(t, cfg, repoProto)
- revisions := make(map[string]git.ObjectID)
- for _, reference := range []string{"refs/heads/master", "refs/heads/feature"} {
- revision, err := repo.ResolveRevision(ctx, git.Revision(reference))
- require.NoError(t, err)
-
- revisions[reference] = revision
- }
+ mainCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"), gittest.WithMessage("main"))
+ featureCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("feature"), gittest.WithMessage("feature"))
+ tag := gittest.WriteTag(t, cfg, repoPath, "v1.0.0", featureCommit.Revision(), gittest.WriteTagConfig{
+ Message: "annotated tag",
+ })
t.Run("single fully qualified branch", func(t *testing.T) {
require.Equal(t, []RevisionResult{
{
- ObjectName: []byte("refs/heads/master"),
- OID: revisions["refs/heads/master"],
+ ObjectName: []byte("refs/heads/main"),
+ OID: mainCommit,
},
- }, readRefs(t, repo, []string{"refs/heads/master"}))
+ }, readRefs(t, repo, []string{"refs/heads/main"}))
})
t.Run("unqualified branch name", func(t *testing.T) {
- require.Nil(t, readRefs(t, repo, []string{"master"}))
+ require.Nil(t, readRefs(t, repo, []string{"main"}))
})
t.Run("multiple branches", func(t *testing.T) {
require.Equal(t, []RevisionResult{
{
ObjectName: []byte("refs/heads/feature"),
- OID: revisions["refs/heads/feature"],
+ OID: featureCommit,
},
{
- ObjectName: []byte("refs/heads/master"),
- OID: revisions["refs/heads/master"],
+ ObjectName: []byte("refs/heads/main"),
+ OID: mainCommit,
},
- }, readRefs(t, repo, []string{"refs/heads/master", "refs/heads/feature"}))
+ }, readRefs(t, repo, []string{"refs/heads/main", "refs/heads/feature"}))
})
t.Run("branches pattern", func(t *testing.T) {
refs := readRefs(t, repo, []string{"refs/heads/*"})
- require.Greater(t, len(refs), 90)
-
- require.Subset(t, refs, []RevisionResult{
+ require.Equal(t, refs, []RevisionResult{
{
- ObjectName: []byte("refs/heads/master"),
- OID: revisions["refs/heads/master"],
+ ObjectName: []byte("refs/heads/feature"),
+ OID: featureCommit,
},
{
- ObjectName: []byte("refs/heads/feature"),
- OID: revisions["refs/heads/feature"],
+ ObjectName: []byte("refs/heads/main"),
+ OID: mainCommit,
},
})
})
@@ -607,18 +602,31 @@ func TestForEachRef(t *testing.T) {
require.Equal(t, refs, []RevisionResult{
{
ObjectName: []byte("tag"),
- OID: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8",
+ OID: tag,
},
{
ObjectName: []byte("peeled"),
- OID: "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9",
+ OID: featureCommit,
},
})
})
t.Run("multiple patterns", func(t *testing.T) {
refs := readRefs(t, repo, []string{"refs/heads/*", "refs/tags/*"})
- require.Greater(t, len(refs), 90)
+ require.Equal(t, refs, []RevisionResult{
+ {
+ ObjectName: []byte("refs/heads/feature"),
+ OID: featureCommit,
+ },
+ {
+ ObjectName: []byte("refs/heads/main"),
+ OID: mainCommit,
+ },
+ {
+ ObjectName: []byte("refs/tags/v1.0.0"),
+ OID: tag,
+ },
+ })
})
t.Run("nonexisting branch", func(t *testing.T) {
@@ -637,8 +645,8 @@ func TestForEachRef(t *testing.T) {
require.True(t, it.Next())
require.NoError(t, it.Err())
require.Equal(t, RevisionResult{
- OID: "e56497bb5f03a90a51293fc6d516788730953899",
- ObjectName: []byte("refs/heads/'test'"),
+ OID: featureCommit,
+ ObjectName: []byte("refs/heads/feature"),
}, it.Result())
cancel()
@@ -652,6 +660,8 @@ func TestForEachRef(t *testing.T) {
}
func TestForEachRef_options(t *testing.T) {
+ t.Parallel()
+
ctx := testhelper.Context(t)
for _, tc := range []struct {
@@ -704,8 +714,11 @@ func TestForEachRef_options(t *testing.T) {
},
},
} {
+ cfg := testcfg.Build(t)
- cfg, repoProto, repoPath := testcfg.BuildWithRepo(t)
+ repoProto, repoPath := gittest.CreateRepository(ctx, t, cfg, gittest.CreateRepositoryConfig{
+ SkipCreationViaService: true,
+ })
repo := localrepo.NewTestRepo(t, cfg, repoProto)
oid := tc.prepare(repoPath, cfg)
diff --git a/internal/git/gitpipe/testhelper_test.go b/internal/git/gitpipe/testhelper_test.go
index 397c270b3..4bc9f18f7 100644
--- a/internal/git/gitpipe/testhelper_test.go
+++ b/internal/git/gitpipe/testhelper_test.go
@@ -1,11 +1,10 @@
-//go:build !gitaly_test_sha256
-
package gitpipe
import (
"testing"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
)
@@ -51,3 +50,10 @@ func (ch *chanObjectIterator) ObjectID() git.ObjectID {
func (ch *chanObjectIterator) ObjectName() []byte {
return []byte("idontcare")
}
+
+func hashDependentObjectSize(sha1Size, sha256Size int64) int64 {
+ if gittest.ObjectHashIsSHA256() {
+ return sha256Size
+ }
+ return sha1Size
+}