diff options
Diffstat (limited to 'formats/packp/ulreq')
-rw-r--r-- | formats/packp/ulreq/decoder.go | 287 | ||||
-rw-r--r-- | formats/packp/ulreq/decoder_test.go | 541 | ||||
-rw-r--r-- | formats/packp/ulreq/encoder.go | 140 | ||||
-rw-r--r-- | formats/packp/ulreq/encoder_test.go | 268 | ||||
-rw-r--r-- | formats/packp/ulreq/ulreq.go | 56 | ||||
-rw-r--r-- | formats/packp/ulreq/ulreq_test.go | 91 |
6 files changed, 0 insertions, 1383 deletions
diff --git a/formats/packp/ulreq/decoder.go b/formats/packp/ulreq/decoder.go deleted file mode 100644 index 63ccd4d..0000000 --- a/formats/packp/ulreq/decoder.go +++ /dev/null @@ -1,287 +0,0 @@ -package ulreq - -import ( - "bytes" - "encoding/hex" - "fmt" - "io" - "strconv" - "time" - - "gopkg.in/src-d/go-git.v4/core" - "gopkg.in/src-d/go-git.v4/formats/packp/pktline" -) - -const ( - hashSize = 40 -) - -var ( - eol = []byte("\n") - sp = []byte(" ") - want = []byte("want ") - shallow = []byte("shallow ") - deepen = []byte("deepen") - deepenCommits = []byte("deepen ") - deepenSince = []byte("deepen-since ") - deepenReference = []byte("deepen-not ") -) - -// A Decoder reads and decodes AdvRef values from an input stream. -type Decoder struct { - s *pktline.Scanner // a pkt-line scanner from the input stream - line []byte // current pkt-line contents, use parser.nextLine() to make it advance - nLine int // current pkt-line number for debugging, begins at 1 - err error // sticky error, use the parser.error() method to fill this out - data *UlReq // parsed data is stored here -} - -// NewDecoder returns a new decoder that reads from r. -// -// Will not read more data from r than necessary. -func NewDecoder(r io.Reader) *Decoder { - return &Decoder{ - s: pktline.NewScanner(r), - } -} - -// Decode reads the next upload-request form its input and -// stores it in the value pointed to by v. -func (d *Decoder) Decode(v *UlReq) error { - d.data = v - - for state := decodeFirstWant; state != nil; { - state = state(d) - } - - return d.err -} - -type decoderStateFn func(*Decoder) decoderStateFn - -// fills out the parser stiky error -func (d *Decoder) error(format string, a ...interface{}) { - d.err = fmt.Errorf("pkt-line %d: %s", d.nLine, - fmt.Sprintf(format, a...)) -} - -// Reads a new pkt-line from the scanner, makes its payload available as -// p.line and increments p.nLine. A successful invocation returns true, -// otherwise, false is returned and the sticky error is filled out -// accordingly. Trims eols at the end of the payloads. -func (d *Decoder) nextLine() bool { - d.nLine++ - - if !d.s.Scan() { - if d.err = d.s.Err(); d.err != nil { - return false - } - - d.error("EOF") - return false - } - - d.line = d.s.Bytes() - d.line = bytes.TrimSuffix(d.line, eol) - - return true -} - -// Expected format: want <hash>[ capabilities] -func decodeFirstWant(d *Decoder) decoderStateFn { - if ok := d.nextLine(); !ok { - return nil - } - - if !bytes.HasPrefix(d.line, want) { - d.error("missing 'want ' prefix") - return nil - } - d.line = bytes.TrimPrefix(d.line, want) - - hash, ok := d.readHash() - if !ok { - return nil - } - d.data.Wants = append(d.data.Wants, hash) - - return decodeCaps -} - -func (d *Decoder) readHash() (core.Hash, bool) { - if len(d.line) < hashSize { - d.err = fmt.Errorf("malformed hash: %v", d.line) - return core.ZeroHash, false - } - - var hash core.Hash - if _, err := hex.Decode(hash[:], d.line[:hashSize]); err != nil { - d.error("invalid hash text: %s", err) - return core.ZeroHash, false - } - d.line = d.line[hashSize:] - - return hash, true -} - -// Expected format: sp cap1 sp cap2 sp cap3... -func decodeCaps(d *Decoder) decoderStateFn { - if len(d.line) == 0 { - return decodeOtherWants - } - - d.line = bytes.TrimPrefix(d.line, sp) - - for _, c := range bytes.Split(d.line, sp) { - name, values := readCapability(c) - d.data.Capabilities.Add(name, values...) - } - - return decodeOtherWants -} - -// Capabilities are a single string or a name=value. -// Even though we are only going to read at moust 1 value, we return -// a slice of values, as Capability.Add receives that. -func readCapability(data []byte) (name string, values []string) { - pair := bytes.SplitN(data, []byte{'='}, 2) - if len(pair) == 2 { - values = append(values, string(pair[1])) - } - - return string(pair[0]), values -} - -// Expected format: want <hash> -func decodeOtherWants(d *Decoder) decoderStateFn { - if ok := d.nextLine(); !ok { - return nil - } - - if bytes.HasPrefix(d.line, shallow) { - return decodeShallow - } - - if bytes.HasPrefix(d.line, deepen) { - return decodeDeepen - } - - if len(d.line) == 0 { - return nil - } - - if !bytes.HasPrefix(d.line, want) { - d.error("unexpected payload while expecting a want: %q", d.line) - return nil - } - d.line = bytes.TrimPrefix(d.line, want) - - hash, ok := d.readHash() - if !ok { - return nil - } - d.data.Wants = append(d.data.Wants, hash) - - return decodeOtherWants -} - -// Expected format: shallow <hash> -func decodeShallow(d *Decoder) decoderStateFn { - if bytes.HasPrefix(d.line, deepen) { - return decodeDeepen - } - - if len(d.line) == 0 { - return nil - } - - if !bytes.HasPrefix(d.line, shallow) { - d.error("unexpected payload while expecting a shallow: %q", d.line) - return nil - } - d.line = bytes.TrimPrefix(d.line, shallow) - - hash, ok := d.readHash() - if !ok { - return nil - } - d.data.Shallows = append(d.data.Shallows, hash) - - if ok := d.nextLine(); !ok { - return nil - } - - return decodeShallow -} - -// Expected format: deepen <n> / deepen-since <ul> / deepen-not <ref> -func decodeDeepen(d *Decoder) decoderStateFn { - if bytes.HasPrefix(d.line, deepenCommits) { - return decodeDeepenCommits - } - - if bytes.HasPrefix(d.line, deepenSince) { - return decodeDeepenSince - } - - if bytes.HasPrefix(d.line, deepenReference) { - return decodeDeepenReference - } - - if len(d.line) == 0 { - return nil - } - - d.error("unexpected deepen specification: %q", d.line) - return nil -} - -func decodeDeepenCommits(d *Decoder) decoderStateFn { - d.line = bytes.TrimPrefix(d.line, deepenCommits) - - var n int - if n, d.err = strconv.Atoi(string(d.line)); d.err != nil { - return nil - } - if n < 0 { - d.err = fmt.Errorf("negative depth") - return nil - } - d.data.Depth = DepthCommits(n) - - return decodeFlush -} - -func decodeDeepenSince(d *Decoder) decoderStateFn { - d.line = bytes.TrimPrefix(d.line, deepenSince) - - var secs int64 - secs, d.err = strconv.ParseInt(string(d.line), 10, 64) - if d.err != nil { - return nil - } - t := time.Unix(secs, 0).UTC() - d.data.Depth = DepthSince(t) - - return decodeFlush -} - -func decodeDeepenReference(d *Decoder) decoderStateFn { - d.line = bytes.TrimPrefix(d.line, deepenReference) - - d.data.Depth = DepthReference(string(d.line)) - - return decodeFlush -} - -func decodeFlush(d *Decoder) decoderStateFn { - if ok := d.nextLine(); !ok { - return nil - } - - if len(d.line) != 0 { - d.err = fmt.Errorf("unexpected payload while expecting a flush-pkt: %q", d.line) - } - - return nil -} diff --git a/formats/packp/ulreq/decoder_test.go b/formats/packp/ulreq/decoder_test.go deleted file mode 100644 index b313395..0000000 --- a/formats/packp/ulreq/decoder_test.go +++ /dev/null @@ -1,541 +0,0 @@ -package ulreq - -import ( - "bytes" - "io" - "sort" - "time" - - "gopkg.in/src-d/go-git.v4/core" - "gopkg.in/src-d/go-git.v4/formats/packp/pktline" - - . "gopkg.in/check.v1" -) - -type SuiteDecoder struct{} - -var _ = Suite(&SuiteDecoder{}) - -func (s *SuiteDecoder) TestEmpty(c *C) { - ur := New() - var buf bytes.Buffer - d := NewDecoder(&buf) - - err := d.Decode(ur) - c.Assert(err, ErrorMatches, "pkt-line 1: EOF") -} - -func (s *SuiteDecoder) TestNoWant(c *C) { - payloads := []string{ - "foobar", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*missing 'want '.*") -} - -func toPktLines(c *C, payloads []string) io.Reader { - var buf bytes.Buffer - e := pktline.NewEncoder(&buf) - err := e.EncodeString(payloads...) - c.Assert(err, IsNil) - - return &buf -} - -func testDecoderErrorMatches(c *C, input io.Reader, pattern string) { - ur := New() - d := NewDecoder(input) - - err := d.Decode(ur) - c.Assert(err, ErrorMatches, pattern) -} - -func (s *SuiteDecoder) TestInvalidFirstHash(c *C) { - payloads := []string{ - "want 6ecf0ef2c2dffb796alberto2219af86ec6584e5\n", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*invalid hash.*") -} - -func (s *SuiteDecoder) TestWantOK(c *C) { - payloads := []string{ - "want 1111111111111111111111111111111111111111", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - c.Assert(ur.Wants, DeepEquals, []core.Hash{ - core.NewHash("1111111111111111111111111111111111111111"), - }) -} - -func testDecodeOK(c *C, payloads []string) *UlReq { - var buf bytes.Buffer - e := pktline.NewEncoder(&buf) - err := e.EncodeString(payloads...) - c.Assert(err, IsNil) - - ur := New() - d := NewDecoder(&buf) - - err = d.Decode(ur) - c.Assert(err, IsNil) - - return ur -} - -func (s *SuiteDecoder) TestWantWithCapabilities(c *C) { - payloads := []string{ - "want 1111111111111111111111111111111111111111 ofs-delta multi_ack", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - c.Assert(ur.Wants, DeepEquals, []core.Hash{ - core.NewHash("1111111111111111111111111111111111111111")}) - - c.Assert(ur.Capabilities.Supports("ofs-delta"), Equals, true) - c.Assert(ur.Capabilities.Supports("multi_ack"), Equals, true) -} - -func (s *SuiteDecoder) TestManyWantsNoCapabilities(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333", - "want 4444444444444444444444444444444444444444", - "want 1111111111111111111111111111111111111111", - "want 2222222222222222222222222222222222222222", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expected := []core.Hash{ - core.NewHash("1111111111111111111111111111111111111111"), - core.NewHash("2222222222222222222222222222222222222222"), - core.NewHash("3333333333333333333333333333333333333333"), - core.NewHash("4444444444444444444444444444444444444444"), - } - - sort.Sort(byHash(ur.Wants)) - sort.Sort(byHash(expected)) - c.Assert(ur.Wants, DeepEquals, expected) -} - -type byHash []core.Hash - -func (a byHash) Len() int { return len(a) } -func (a byHash) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byHash) Less(i, j int) bool { - ii := [20]byte(a[i]) - jj := [20]byte(a[j]) - return bytes.Compare(ii[:], jj[:]) < 0 -} - -func (s *SuiteDecoder) TestManyWantsBadWant(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333", - "want 4444444444444444444444444444444444444444", - "foo", - "want 2222222222222222222222222222222222222222", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected payload.*") -} - -func (s *SuiteDecoder) TestManyWantsInvalidHash(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333", - "want 4444444444444444444444444444444444444444", - "want 1234567890abcdef", - "want 2222222222222222222222222222222222222222", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*malformed hash.*") -} - -func (s *SuiteDecoder) TestManyWantsWithCapabilities(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "want 4444444444444444444444444444444444444444", - "want 1111111111111111111111111111111111111111", - "want 2222222222222222222222222222222222222222", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expected := []core.Hash{ - core.NewHash("1111111111111111111111111111111111111111"), - core.NewHash("2222222222222222222222222222222222222222"), - core.NewHash("3333333333333333333333333333333333333333"), - core.NewHash("4444444444444444444444444444444444444444"), - } - - sort.Sort(byHash(ur.Wants)) - sort.Sort(byHash(expected)) - c.Assert(ur.Wants, DeepEquals, expected) - - c.Assert(ur.Capabilities.Supports("ofs-delta"), Equals, true) - c.Assert(ur.Capabilities.Supports("multi_ack"), Equals, true) -} - -func (s *SuiteDecoder) TestSingleShallowSingleWant(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expectedWants := []core.Hash{ - core.NewHash("3333333333333333333333333333333333333333"), - } - - expectedShallows := []core.Hash{ - core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - } - - c.Assert(ur.Wants, DeepEquals, expectedWants) - c.Assert(ur.Capabilities.Supports("ofs-delta"), Equals, true) - c.Assert(ur.Capabilities.Supports("multi_ack"), Equals, true) - - c.Assert(ur.Shallows, DeepEquals, expectedShallows) -} - -func (s *SuiteDecoder) TestSingleShallowManyWants(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "want 4444444444444444444444444444444444444444", - "want 1111111111111111111111111111111111111111", - "want 2222222222222222222222222222222222222222", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expectedWants := []core.Hash{ - core.NewHash("1111111111111111111111111111111111111111"), - core.NewHash("2222222222222222222222222222222222222222"), - core.NewHash("3333333333333333333333333333333333333333"), - core.NewHash("4444444444444444444444444444444444444444"), - } - sort.Sort(byHash(expectedWants)) - - expectedShallows := []core.Hash{ - core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - } - - sort.Sort(byHash(ur.Wants)) - c.Assert(ur.Wants, DeepEquals, expectedWants) - c.Assert(ur.Capabilities.Supports("ofs-delta"), Equals, true) - c.Assert(ur.Capabilities.Supports("multi_ack"), Equals, true) - - c.Assert(ur.Shallows, DeepEquals, expectedShallows) -} - -func (s *SuiteDecoder) TestManyShallowSingleWant(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - "shallow cccccccccccccccccccccccccccccccccccccccc", - "shallow dddddddddddddddddddddddddddddddddddddddd", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expectedWants := []core.Hash{ - core.NewHash("3333333333333333333333333333333333333333"), - } - - expectedShallows := []core.Hash{ - core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - core.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), - core.NewHash("cccccccccccccccccccccccccccccccccccccccc"), - core.NewHash("dddddddddddddddddddddddddddddddddddddddd"), - } - sort.Sort(byHash(expectedShallows)) - - c.Assert(ur.Wants, DeepEquals, expectedWants) - c.Assert(ur.Capabilities.Supports("ofs-delta"), Equals, true) - c.Assert(ur.Capabilities.Supports("multi_ack"), Equals, true) - - sort.Sort(byHash(ur.Shallows)) - c.Assert(ur.Shallows, DeepEquals, expectedShallows) -} - -func (s *SuiteDecoder) TestManyShallowManyWants(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "want 4444444444444444444444444444444444444444", - "want 1111111111111111111111111111111111111111", - "want 2222222222222222222222222222222222222222", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - "shallow cccccccccccccccccccccccccccccccccccccccc", - "shallow dddddddddddddddddddddddddddddddddddddddd", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expectedWants := []core.Hash{ - core.NewHash("1111111111111111111111111111111111111111"), - core.NewHash("2222222222222222222222222222222222222222"), - core.NewHash("3333333333333333333333333333333333333333"), - core.NewHash("4444444444444444444444444444444444444444"), - } - sort.Sort(byHash(expectedWants)) - - expectedShallows := []core.Hash{ - core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - core.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), - core.NewHash("cccccccccccccccccccccccccccccccccccccccc"), - core.NewHash("dddddddddddddddddddddddddddddddddddddddd"), - } - sort.Sort(byHash(expectedShallows)) - - sort.Sort(byHash(ur.Wants)) - c.Assert(ur.Wants, DeepEquals, expectedWants) - c.Assert(ur.Capabilities.Supports("ofs-delta"), Equals, true) - c.Assert(ur.Capabilities.Supports("multi_ack"), Equals, true) - - sort.Sort(byHash(ur.Shallows)) - c.Assert(ur.Shallows, DeepEquals, expectedShallows) -} - -func (s *SuiteDecoder) TestMalformedShallow(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "shalow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected payload.*") -} - -func (s *SuiteDecoder) TestMalformedShallowHash(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*malformed hash.*") -} - -func (s *SuiteDecoder) TestMalformedShallowManyShallows(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "shalow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - "shallow cccccccccccccccccccccccccccccccccccccccc", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected payload.*") -} - -func (s *SuiteDecoder) TestMalformedDeepenSpec(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "deepen-foo 34", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected deepen.*") -} - -func (s *SuiteDecoder) TestMalformedDeepenSingleWant(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "depth 32", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected payload.*") -} - -func (s *SuiteDecoder) TestMalformedDeepenMultiWant(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "want 2222222222222222222222222222222222222222", - "depth 32", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected payload.*") -} - -func (s *SuiteDecoder) TestMalformedDeepenWithSingleShallow(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "shallow 2222222222222222222222222222222222222222", - "depth 32", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected payload.*") -} - -func (s *SuiteDecoder) TestMalformedDeepenWithMultiShallow(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "shallow 2222222222222222222222222222222222222222", - "shallow 5555555555555555555555555555555555555555", - "depth 32", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected payload.*") -} - -func (s *SuiteDecoder) TestDeepenCommits(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "deepen 1234", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - c.Assert(ur.Depth, FitsTypeOf, DepthCommits(0)) - commits, ok := ur.Depth.(DepthCommits) - c.Assert(ok, Equals, true) - c.Assert(int(commits), Equals, 1234) -} - -func (s *SuiteDecoder) TestDeepenCommitsInfiniteInplicit(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "deepen 0", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - c.Assert(ur.Depth, FitsTypeOf, DepthCommits(0)) - commits, ok := ur.Depth.(DepthCommits) - c.Assert(ok, Equals, true) - c.Assert(int(commits), Equals, 0) -} - -func (s *SuiteDecoder) TestDeepenCommitsInfiniteExplicit(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - c.Assert(ur.Depth, FitsTypeOf, DepthCommits(0)) - commits, ok := ur.Depth.(DepthCommits) - c.Assert(ok, Equals, true) - c.Assert(int(commits), Equals, 0) -} - -func (s *SuiteDecoder) TestMalformedDeepenCommits(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "deepen -32", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*negative depth.*") -} - -func (s *SuiteDecoder) TestDeepenCommitsEmpty(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "deepen ", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*invalid syntax.*") -} - -func (s *SuiteDecoder) TestDeepenSince(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "deepen-since 1420167845", // 2015-01-02T03:04:05+00:00 - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expected := time.Date(2015, time.January, 2, 3, 4, 5, 0, time.UTC) - - c.Assert(ur.Depth, FitsTypeOf, DepthSince(time.Now())) - since, ok := ur.Depth.(DepthSince) - c.Assert(ok, Equals, true) - c.Assert(time.Time(since).Equal(expected), Equals, true, - Commentf("obtained=%s\nexpected=%s", time.Time(since), expected)) -} - -func (s *SuiteDecoder) TestDeepenReference(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "deepen-not refs/heads/master", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expected := "refs/heads/master" - - c.Assert(ur.Depth, FitsTypeOf, DepthReference("")) - reference, ok := ur.Depth.(DepthReference) - c.Assert(ok, Equals, true) - c.Assert(string(reference), Equals, expected) -} - -func (s *SuiteDecoder) TestAll(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "want 4444444444444444444444444444444444444444", - "want 1111111111111111111111111111111111111111", - "want 2222222222222222222222222222222222222222", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - "shallow cccccccccccccccccccccccccccccccccccccccc", - "shallow dddddddddddddddddddddddddddddddddddddddd", - "deepen 1234", - pktline.FlushString, - } - ur := testDecodeOK(c, payloads) - - expectedWants := []core.Hash{ - core.NewHash("1111111111111111111111111111111111111111"), - core.NewHash("2222222222222222222222222222222222222222"), - core.NewHash("3333333333333333333333333333333333333333"), - core.NewHash("4444444444444444444444444444444444444444"), - } - sort.Sort(byHash(expectedWants)) - sort.Sort(byHash(ur.Wants)) - c.Assert(ur.Wants, DeepEquals, expectedWants) - - c.Assert(ur.Capabilities.Supports("ofs-delta"), Equals, true) - c.Assert(ur.Capabilities.Supports("multi_ack"), Equals, true) - - expectedShallows := []core.Hash{ - core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), - core.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), - core.NewHash("cccccccccccccccccccccccccccccccccccccccc"), - core.NewHash("dddddddddddddddddddddddddddddddddddddddd"), - } - sort.Sort(byHash(expectedShallows)) - sort.Sort(byHash(ur.Shallows)) - c.Assert(ur.Shallows, DeepEquals, expectedShallows) - - c.Assert(ur.Depth, FitsTypeOf, DepthCommits(0)) - commits, ok := ur.Depth.(DepthCommits) - c.Assert(ok, Equals, true) - c.Assert(int(commits), Equals, 1234) -} - -func (s *SuiteDecoder) TestExtraData(c *C) { - payloads := []string{ - "want 3333333333333333333333333333333333333333 ofs-delta multi_ack", - "deepen 32", - "foo", - pktline.FlushString, - } - r := toPktLines(c, payloads) - testDecoderErrorMatches(c, r, ".*unexpected payload.*") -} diff --git a/formats/packp/ulreq/encoder.go b/formats/packp/ulreq/encoder.go deleted file mode 100644 index 1e40b63..0000000 --- a/formats/packp/ulreq/encoder.go +++ /dev/null @@ -1,140 +0,0 @@ -package ulreq - -import ( - "fmt" - "io" - "sort" - "time" - - "gopkg.in/src-d/go-git.v4/core" - "gopkg.in/src-d/go-git.v4/formats/packp/pktline" -) - -// An Encoder writes UlReq values to an output stream. -type Encoder struct { - pe *pktline.Encoder // where to write the encoded data - data *UlReq // the data to encode - sortedWants []string - err error // sticky error -} - -// NewEncoder returns a new encoder that writes to w. -func NewEncoder(w io.Writer) *Encoder { - return &Encoder{ - pe: pktline.NewEncoder(w), - } -} - -// Encode writes the UlReq encoding of v to the stream. -// -// All the payloads will end with a newline character. Wants and -// shallows are sorted alphabetically. A depth of 0 means no depth -// request is sent. -func (e *Encoder) Encode(v *UlReq) error { - if len(v.Wants) == 0 { - return fmt.Errorf("empty wants provided") - } - - e.data = v - e.sortedWants = sortHashes(v.Wants) - - for state := encodeFirstWant; state != nil; { - state = state(e) - } - - return e.err -} - -type encoderStateFn func(*Encoder) encoderStateFn - -func sortHashes(list []core.Hash) []string { - sorted := make([]string, len(list)) - for i, hash := range list { - sorted[i] = hash.String() - } - sort.Strings(sorted) - - return sorted -} - -func encodeFirstWant(e *Encoder) encoderStateFn { - var err error - if e.data.Capabilities.IsEmpty() { - err = e.pe.Encodef("want %s\n", e.sortedWants[0]) - } else { - e.data.Capabilities.Sort() - err = e.pe.Encodef( - "want %s %s\n", - e.sortedWants[0], - e.data.Capabilities.String(), - ) - } - if err != nil { - e.err = fmt.Errorf("encoding first want line: %s", err) - return nil - } - - return encodeAditionalWants -} - -func encodeAditionalWants(e *Encoder) encoderStateFn { - for _, w := range e.sortedWants[1:] { - if err := e.pe.Encodef("want %s\n", w); err != nil { - e.err = fmt.Errorf("encoding want %q: %s", w, err) - return nil - } - } - - return encodeShallows -} - -func encodeShallows(e *Encoder) encoderStateFn { - sorted := sortHashes(e.data.Shallows) - for _, s := range sorted { - if err := e.pe.Encodef("shallow %s\n", s); err != nil { - e.err = fmt.Errorf("encoding shallow %q: %s", s, err) - return nil - } - } - - return encodeDepth -} - -func encodeDepth(e *Encoder) encoderStateFn { - switch depth := e.data.Depth.(type) { - case DepthCommits: - if depth != 0 { - commits := int(depth) - if err := e.pe.Encodef("deepen %d\n", commits); err != nil { - e.err = fmt.Errorf("encoding depth %d: %s", depth, err) - return nil - } - } - case DepthSince: - when := time.Time(depth).UTC() - if err := e.pe.Encodef("deepen-since %d\n", when.Unix()); err != nil { - e.err = fmt.Errorf("encoding depth %s: %s", when, err) - return nil - } - case DepthReference: - reference := string(depth) - if err := e.pe.Encodef("deepen-not %s\n", reference); err != nil { - e.err = fmt.Errorf("encoding depth %s: %s", reference, err) - return nil - } - default: - e.err = fmt.Errorf("unsupported depth type") - return nil - } - - return encodeFlush -} - -func encodeFlush(e *Encoder) encoderStateFn { - if err := e.pe.Flush(); err != nil { - e.err = fmt.Errorf("encoding flush-pkt: %s", err) - return nil - } - - return nil -} diff --git a/formats/packp/ulreq/encoder_test.go b/formats/packp/ulreq/encoder_test.go deleted file mode 100644 index 56a8c2a..0000000 --- a/formats/packp/ulreq/encoder_test.go +++ /dev/null @@ -1,268 +0,0 @@ -package ulreq - -import ( - "bytes" - "time" - - "gopkg.in/src-d/go-git.v4/core" - "gopkg.in/src-d/go-git.v4/formats/packp/pktline" - - . "gopkg.in/check.v1" -) - -type SuiteEncoder struct{} - -var _ = Suite(&SuiteEncoder{}) - -// returns a byte slice with the pkt-lines for the given payloads. -func pktlines(c *C, payloads ...string) []byte { - var buf bytes.Buffer - e := pktline.NewEncoder(&buf) - - err := e.EncodeString(payloads...) - c.Assert(err, IsNil, Commentf("building pktlines for %v\n", payloads)) - - return buf.Bytes() -} - -func testEncode(c *C, ur *UlReq, expectedPayloads []string) { - var buf bytes.Buffer - e := NewEncoder(&buf) - - err := e.Encode(ur) - c.Assert(err, IsNil) - obtained := buf.Bytes() - - expected := pktlines(c, expectedPayloads...) - - comment := Commentf("\nobtained = %s\nexpected = %s\n", string(obtained), string(expected)) - - c.Assert(obtained, DeepEquals, expected, comment) -} - -func testEncodeError(c *C, ur *UlReq, expectedErrorRegEx string) { - var buf bytes.Buffer - e := NewEncoder(&buf) - - err := e.Encode(ur) - c.Assert(err, ErrorMatches, expectedErrorRegEx) -} - -func (s *SuiteEncoder) TestZeroValue(c *C) { - ur := New() - expectedErrorRegEx := ".*empty wants.*" - - testEncodeError(c, ur, expectedErrorRegEx) -} - -func (s *SuiteEncoder) TestOneWant(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - - expected := []string{ - "want 1111111111111111111111111111111111111111\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestOneWantWithCapabilities(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Capabilities.Add("sysref", "HEAD:/refs/heads/master") - ur.Capabilities.Add("multi_ack") - ur.Capabilities.Add("thin-pack") - ur.Capabilities.Add("side-band") - ur.Capabilities.Add("ofs-delta") - - expected := []string{ - "want 1111111111111111111111111111111111111111 multi_ack ofs-delta side-band sysref=HEAD:/refs/heads/master thin-pack\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestWants(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("4444444444444444444444444444444444444444")) - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Wants = append(ur.Wants, core.NewHash("3333333333333333333333333333333333333333")) - ur.Wants = append(ur.Wants, core.NewHash("2222222222222222222222222222222222222222")) - ur.Wants = append(ur.Wants, core.NewHash("5555555555555555555555555555555555555555")) - - expected := []string{ - "want 1111111111111111111111111111111111111111\n", - "want 2222222222222222222222222222222222222222\n", - "want 3333333333333333333333333333333333333333\n", - "want 4444444444444444444444444444444444444444\n", - "want 5555555555555555555555555555555555555555\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestWantsWithCapabilities(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("4444444444444444444444444444444444444444")) - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Wants = append(ur.Wants, core.NewHash("3333333333333333333333333333333333333333")) - ur.Wants = append(ur.Wants, core.NewHash("2222222222222222222222222222222222222222")) - ur.Wants = append(ur.Wants, core.NewHash("5555555555555555555555555555555555555555")) - - ur.Capabilities.Add("sysref", "HEAD:/refs/heads/master") - ur.Capabilities.Add("multi_ack") - ur.Capabilities.Add("thin-pack") - ur.Capabilities.Add("side-band") - ur.Capabilities.Add("ofs-delta") - - expected := []string{ - "want 1111111111111111111111111111111111111111 multi_ack ofs-delta side-band sysref=HEAD:/refs/heads/master thin-pack\n", - "want 2222222222222222222222222222222222222222\n", - "want 3333333333333333333333333333333333333333\n", - "want 4444444444444444444444444444444444444444\n", - "want 5555555555555555555555555555555555555555\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestShallow(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Capabilities.Add("multi_ack") - ur.Shallows = append(ur.Shallows, core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) - - expected := []string{ - "want 1111111111111111111111111111111111111111 multi_ack\n", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestManyShallows(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Capabilities.Add("multi_ack") - ur.Shallows = append(ur.Shallows, core.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")) - ur.Shallows = append(ur.Shallows, core.NewHash("dddddddddddddddddddddddddddddddddddddddd")) - ur.Shallows = append(ur.Shallows, core.NewHash("cccccccccccccccccccccccccccccccccccccccc")) - ur.Shallows = append(ur.Shallows, core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) - - expected := []string{ - "want 1111111111111111111111111111111111111111 multi_ack\n", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", - "shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n", - "shallow cccccccccccccccccccccccccccccccccccccccc\n", - "shallow dddddddddddddddddddddddddddddddddddddddd\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestDepthCommits(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Depth = DepthCommits(1234) - - expected := []string{ - "want 1111111111111111111111111111111111111111\n", - "deepen 1234\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestDepthSinceUTC(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - since := time.Date(2015, time.January, 2, 3, 4, 5, 0, time.UTC) - ur.Depth = DepthSince(since) - - expected := []string{ - "want 1111111111111111111111111111111111111111\n", - "deepen-since 1420167845\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestDepthSinceNonUTC(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - berlin, err := time.LoadLocation("Europe/Berlin") - c.Assert(err, IsNil) - since := time.Date(2015, time.January, 2, 3, 4, 5, 0, berlin) - // since value is 2015-01-02 03:04:05 +0100 UTC (Europe/Berlin) or - // 2015-01-02 02:04:05 +0000 UTC, which is 1420164245 Unix seconds. - ur.Depth = DepthSince(since) - - expected := []string{ - "want 1111111111111111111111111111111111111111\n", - "deepen-since 1420164245\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestDepthReference(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Depth = DepthReference("refs/heads/feature-foo") - - expected := []string{ - "want 1111111111111111111111111111111111111111\n", - "deepen-not refs/heads/feature-foo\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} - -func (s *SuiteEncoder) TestAll(c *C) { - ur := New() - ur.Wants = append(ur.Wants, core.NewHash("4444444444444444444444444444444444444444")) - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Wants = append(ur.Wants, core.NewHash("3333333333333333333333333333333333333333")) - ur.Wants = append(ur.Wants, core.NewHash("2222222222222222222222222222222222222222")) - ur.Wants = append(ur.Wants, core.NewHash("5555555555555555555555555555555555555555")) - - ur.Capabilities.Add("sysref", "HEAD:/refs/heads/master") - ur.Capabilities.Add("multi_ack") - ur.Capabilities.Add("thin-pack") - ur.Capabilities.Add("side-band") - ur.Capabilities.Add("ofs-delta") - - ur.Shallows = append(ur.Shallows, core.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")) - ur.Shallows = append(ur.Shallows, core.NewHash("dddddddddddddddddddddddddddddddddddddddd")) - ur.Shallows = append(ur.Shallows, core.NewHash("cccccccccccccccccccccccccccccccccccccccc")) - ur.Shallows = append(ur.Shallows, core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) - - since := time.Date(2015, time.January, 2, 3, 4, 5, 0, time.UTC) - ur.Depth = DepthSince(since) - - expected := []string{ - "want 1111111111111111111111111111111111111111 multi_ack ofs-delta side-band sysref=HEAD:/refs/heads/master thin-pack\n", - "want 2222222222222222222222222222222222222222\n", - "want 3333333333333333333333333333333333333333\n", - "want 4444444444444444444444444444444444444444\n", - "want 5555555555555555555555555555555555555555\n", - "shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", - "shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n", - "shallow cccccccccccccccccccccccccccccccccccccccc\n", - "shallow dddddddddddddddddddddddddddddddddddddddd\n", - "deepen-since 1420167845\n", - pktline.FlushString, - } - - testEncode(c, ur, expected) -} diff --git a/formats/packp/ulreq/ulreq.go b/formats/packp/ulreq/ulreq.go deleted file mode 100644 index e47450a..0000000 --- a/formats/packp/ulreq/ulreq.go +++ /dev/null @@ -1,56 +0,0 @@ -// Package ulreq implements encoding and decoding upload-request -// messages from a git-upload-pack command. -package ulreq - -import ( - "time" - - "gopkg.in/src-d/go-git.v4/core" - "gopkg.in/src-d/go-git.v4/formats/packp" -) - -// UlReq values represent the information transmitted on a -// upload-request message. Values from this type are not zero-value -// safe, use the New function instead. -type UlReq struct { - Capabilities *packp.Capabilities - Wants []core.Hash - Shallows []core.Hash - Depth Depth -} - -// Depth values stores the desired depth of the requested packfile: see -// DepthCommit, DepthSince and DepthReference. -type Depth interface { - isDepth() -} - -// DepthCommits values stores the maximum number of requested commits in -// the packfile. Zero means infinite. A negative value will have -// undefined consecuences. -type DepthCommits int - -func (d DepthCommits) isDepth() {} - -// DepthSince values requests only commits newer than the specified time. -type DepthSince time.Time - -func (d DepthSince) isDepth() {} - -// DepthReference requests only commits not to found in the specified reference. -type DepthReference string - -func (d DepthReference) isDepth() {} - -// New returns a pointer to a new UlReq value, ready to be used. It has -// no capabilities, wants or shallows and an infinite depth. Please -// note that to encode an upload-request it has to have at least one -// wanted hash. -func New() *UlReq { - return &UlReq{ - Capabilities: packp.NewCapabilities(), - Wants: []core.Hash{}, - Shallows: []core.Hash{}, - Depth: DepthCommits(0), - } -} diff --git a/formats/packp/ulreq/ulreq_test.go b/formats/packp/ulreq/ulreq_test.go deleted file mode 100644 index 2c5e85a..0000000 --- a/formats/packp/ulreq/ulreq_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package ulreq - -import ( - "fmt" - "os" - "strings" - "testing" - "time" - - "gopkg.in/src-d/go-git.v4/core" - "gopkg.in/src-d/go-git.v4/formats/packp/pktline" - - . "gopkg.in/check.v1" -) - -func Test(t *testing.T) { TestingT(t) } - -func ExampleEncoder_Encode() { - // Create an empty UlReq with the contents you want... - ur := New() - - // Add a couple of wants - ur.Wants = append(ur.Wants, core.NewHash("3333333333333333333333333333333333333333")) - ur.Wants = append(ur.Wants, core.NewHash("1111111111111111111111111111111111111111")) - ur.Wants = append(ur.Wants, core.NewHash("2222222222222222222222222222222222222222")) - - // And some capabilities you will like the server to use - ur.Capabilities.Add("sysref", "HEAD:/refs/heads/master") - ur.Capabilities.Add("ofs-delta") - - // Add a couple of shallows - ur.Shallows = append(ur.Shallows, core.NewHash("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")) - ur.Shallows = append(ur.Shallows, core.NewHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) - - // And retrict the answer of the server to commits newer than "2015-01-02 03:04:05 UTC" - since := time.Date(2015, time.January, 2, 3, 4, 5, 0, time.UTC) - ur.Depth = DepthSince(since) - - // Create a new Encode for the stdout... - e := NewEncoder(os.Stdout) - // ...and encode the upload-request to it. - _ = e.Encode(ur) // ignoring errors for brevity - // Output: - // 005bwant 1111111111111111111111111111111111111111 ofs-delta sysref=HEAD:/refs/heads/master - // 0032want 2222222222222222222222222222222222222222 - // 0032want 3333333333333333333333333333333333333333 - // 0035shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - // 0035shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - // 001cdeepen-since 1420167845 - // 0000 -} - -func ExampleDecoder_Decode() { - // Here is a raw advertised-ref message. - raw := "" + - "005bwant 1111111111111111111111111111111111111111 ofs-delta sysref=HEAD:/refs/heads/master\n" + - "0032want 2222222222222222222222222222222222222222\n" + - "0032want 3333333333333333333333333333333333333333\n" + - "0035shallow aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + - "0035shallow bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + - "001cdeepen-since 1420167845\n" + // 2015-01-02 03:04:05 +0000 UTC - pktline.FlushString - - // Use the raw message as our input. - input := strings.NewReader(raw) - - // Create the Decoder reading from our input. - d := NewDecoder(input) - - // Decode the input into a newly allocated UlReq value. - ur := New() - _ = d.Decode(ur) // error check ignored for brevity - - // Do something interesting with the UlReq, e.g. print its contents. - fmt.Println("capabilities =", ur.Capabilities.String()) - fmt.Println("wants =", ur.Wants) - fmt.Println("shallows =", ur.Shallows) - switch depth := ur.Depth.(type) { - case DepthCommits: - fmt.Println("depth =", int(depth)) - case DepthSince: - fmt.Println("depth =", time.Time(depth)) - case DepthReference: - fmt.Println("depth =", string(depth)) - } - // Output: - // capabilities = ofs-delta sysref=HEAD:/refs/heads/master - // wants = [1111111111111111111111111111111111111111 2222222222222222222222222222222222222222 3333333333333333333333333333333333333333] - // shallows = [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] - // depth = 2015-01-02 03:04:05 +0000 UTC -} |