Skip to content

Commit 6b7fe1c

Browse files
committed
packp: client-side filter capability support
1 parent a6e934f commit 6b7fe1c

File tree

5 files changed

+109
-0
lines changed

5 files changed

+109
-0
lines changed

plumbing/protocol/packp/filter.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package packp
2+
3+
import (
4+
"fmt"
5+
"github.com/go-git/go-git/v5/plumbing"
6+
"net/url"
7+
"strings"
8+
)
9+
10+
// Filter values enable the partial clone capability which causes
11+
// the server to omit objects that match the filter.
12+
type Filter string
13+
14+
// FilterBlobNone omits all blobs.
15+
func FilterBlobNone() Filter {
16+
return "blob:none"
17+
}
18+
19+
// FilterBlobLimit omits blobs of size at least n bytes. n can be zero,
20+
// in which case all blobs will be omitted.
21+
func FilterBlobLimit(n uint64) Filter {
22+
return Filter(fmt.Sprintf("blob:limit=%d", n))
23+
}
24+
25+
// FilterTreeDepth omits all blobs and trees whose depth from the root tree
26+
// is larger or equal to depth.
27+
func FilterTreeDepth(depth uint64) Filter {
28+
return Filter(fmt.Sprintf("tree:%d", depth))
29+
}
30+
31+
// FilterObjectType omits all objects which are not of the requested type t.
32+
func FilterObjectType(t plumbing.ObjectType) Filter {
33+
return Filter(fmt.Sprintf("object:type=%s", t.String()))
34+
}
35+
36+
// FilterCombine combines multiple Filter values together.
37+
func FilterCombine(filters ...Filter) Filter {
38+
var escapedFilters []string
39+
40+
for _, filter := range filters {
41+
escapedFilters = append(escapedFilters, url.QueryEscape(string(filter)))
42+
}
43+
44+
return Filter(fmt.Sprintf("combine:%s", strings.Join(escapedFilters, "+")))
45+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package packp
2+
3+
import (
4+
"github.com/go-git/go-git/v5/plumbing"
5+
"github.com/stretchr/testify/require"
6+
"testing"
7+
)
8+
9+
func TestFilterBlobNone(t *testing.T) {
10+
require.EqualValues(t, "blob:none", FilterBlobNone())
11+
}
12+
13+
func TestFilterBlobLimit(t *testing.T) {
14+
require.EqualValues(t, "blob:limit=0", FilterBlobLimit(0))
15+
require.EqualValues(t, "blob:limit=1000", FilterBlobLimit(1000))
16+
}
17+
18+
func TestFilterTreeDepth(t *testing.T) {
19+
require.EqualValues(t, "tree:0", FilterTreeDepth(0))
20+
require.EqualValues(t, "tree:1", FilterTreeDepth(1))
21+
require.EqualValues(t, "tree:2", FilterTreeDepth(2))
22+
}
23+
24+
func TestFilterObjectType(t *testing.T) {
25+
require.EqualValues(t, "object:type=tag", FilterObjectType(plumbing.TagObject))
26+
require.EqualValues(t, "object:type=commit", FilterObjectType(plumbing.CommitObject))
27+
require.EqualValues(t, "object:type=tree", FilterObjectType(plumbing.TreeObject))
28+
require.EqualValues(t, "object:type=blob", FilterObjectType(plumbing.BlobObject))
29+
}
30+
31+
func TestFilterCombine(t *testing.T) {
32+
require.EqualValues(t, "combine:tree%3A2+blob%3Anone",
33+
FilterCombine(
34+
FilterTreeDepth(2),
35+
FilterBlobNone(),
36+
),
37+
)
38+
}

plumbing/protocol/packp/ulreq.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type UploadRequest struct {
1717
Wants []plumbing.Hash
1818
Shallows []plumbing.Hash
1919
Depth Depth
20+
Filter Filter
2021
}
2122

2223
// Depth values stores the desired depth of the requested packfile: see

plumbing/protocol/packp/ulreq_encode.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,17 @@ func (e *ulReqEncoder) encodeDepth() stateFn {
132132
return nil
133133
}
134134

135+
return e.encodeFilter
136+
}
137+
138+
func (e *ulReqEncoder) encodeFilter() stateFn {
139+
if filter := e.data.Filter; filter != "" {
140+
if err := e.pe.Encodef("filter %s\n", filter); err != nil {
141+
e.err = fmt.Errorf("encoding filter %s: %s", filter, err)
142+
return nil
143+
}
144+
}
145+
135146
return e.encodeFlush
136147
}
137148

plumbing/protocol/packp/ulreq_encode_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,20 @@ func (s *UlReqEncodeSuite) TestDepthReference(c *C) {
273273
testUlReqEncode(c, ur, expected)
274274
}
275275

276+
func (s *UlReqEncodeSuite) TestFilter(c *C) {
277+
ur := NewUploadRequest()
278+
ur.Wants = append(ur.Wants, plumbing.NewHash("1111111111111111111111111111111111111111"))
279+
ur.Filter = FilterTreeDepth(0)
280+
281+
expected := []string{
282+
"want 1111111111111111111111111111111111111111\n",
283+
"filter tree:0\n",
284+
pktline.FlushString,
285+
}
286+
287+
testUlReqEncode(c, ur, expected)
288+
}
289+
276290
func (s *UlReqEncodeSuite) TestAll(c *C) {
277291
ur := NewUploadRequest()
278292
ur.Wants = append(ur.Wants,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy