Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 0023a4a

Browse files
committed
dotgit: synced write packfile and index generation
1 parent 0d67016 commit 0023a4a

File tree

12 files changed

+314
-119
lines changed

12 files changed

+314
-119
lines changed

.vscode/launch.json

Lines changed: 0 additions & 18 deletions
This file was deleted.

common_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ func (s *BaseSuite) buildRepositories(c *C) {
5555
defer f.Close()
5656

5757
n := packfile.NewScanner(f)
58-
d := packfile.NewDecoder(n, r.s.ObjectStorage())
59-
_, err := d.Decode()
58+
d, err := packfile.NewDecoder(n, r.s.ObjectStorage())
59+
c.Assert(err, IsNil)
60+
_, err = d.Decode()
6061
c.Assert(err, IsNil)
6162

6263
s.Repositories[fixture.URL] = r
@@ -151,7 +152,8 @@ func unpackFixtures(c *C, fixtures ...[]packedFixture) map[string]*Repository {
151152
c.Assert(err, IsNil, comment)
152153

153154
r := packfile.NewScanner(f)
154-
d := packfile.NewDecoder(r, repos[fixture.url].s.ObjectStorage())
155+
d, err := packfile.NewDecoder(r, repos[fixture.url].s.ObjectStorage())
156+
c.Assert(err, IsNil, comment)
155157
_, err = d.Decode()
156158
c.Assert(err, IsNil, comment)
157159
c.Assert(f.Close(), IsNil, comment)

examples/clone/main.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"fmt"
45
"io"
56
"os"
67
"path/filepath"
@@ -15,15 +16,15 @@ func main() {
1516
url := os.Args[1]
1617
directory := os.Args[2]
1718

18-
r := git.NewMemoryRepository()
19+
r, err := git.NewFilesystemRepository(directory)
20+
checkIfError(err)
1921

2022
// Clone the given repository, using depth we create a shallow clone :
2123
// > git clone <url> --depth 1
2224
color.Blue("git clone %s --depth 1 %s", url, directory)
2325

24-
err := r.Clone(&git.CloneOptions{
25-
URL: url,
26-
Depth: 1,
26+
err = r.Clone(&git.CloneOptions{
27+
URL: url,
2728
})
2829
checkIfError(err)
2930

@@ -34,6 +35,9 @@ func main() {
3435
commit, err := r.Commit(ref.Hash())
3536
checkIfError(err)
3637

38+
fmt.Println(commit)
39+
os.Exit(0)
40+
3741
// ... we get all the files from the commit
3842
files, err := commit.Files()
3943
checkIfError(err)

formats/idxfile/decoder_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ func (s *IdxfileSuite) TestDecodeCRCs(c *C) {
4242
scanner := packfile.NewScanner(f.Packfile())
4343
storage := memory.NewStorage()
4444

45-
pd := packfile.NewDecoder(scanner, storage.ObjectStorage())
46-
_, err := pd.Decode()
45+
pd, err := packfile.NewDecoder(scanner, storage.ObjectStorage())
46+
c.Assert(err, IsNil)
47+
_, err = pd.Decode()
4748
c.Assert(err, IsNil)
4849

4950
i := &Idxfile{Version: VersionSupported}

formats/packfile/decoder.go

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ var (
3030
// ErrZLib is returned by Decode when there was an error unzipping
3131
// the packfile contents.
3232
ErrZLib = NewError("zlib reading error")
33-
// ErrNotSeeker not seeker supported
34-
ErrNotSeeker = NewError("no seeker capable decode")
3533
// ErrCannotRecall is returned by RecallByOffset or RecallByHash if the object
3634
// to recall cannot be returned.
3735
ErrCannotRecall = NewError("cannot recall object")
36+
// ErrNonSeekable is returned if a NewDecoder is used with a non-seekable
37+
// reader and without a core.ObjectStorage or ReadObjectAt method is called
38+
// without a seekable scanner
39+
ErrNonSeekable = NewError("non-seekable scanner")
3840
)
3941

4042
// Decoder reads and decodes packfiles from an input stream.
@@ -49,16 +51,25 @@ type Decoder struct {
4951
}
5052

5153
// NewDecoder returns a new Decoder that reads from r.
52-
func NewDecoder(s *Scanner, o core.ObjectStorage) *Decoder {
54+
func NewDecoder(s *Scanner, o core.ObjectStorage) (*Decoder, error) {
55+
if !s.IsSeekable && o == nil {
56+
return nil, ErrNonSeekable
57+
}
58+
59+
var tx core.TxObjectStorage
60+
if o != nil {
61+
tx = o.Begin()
62+
}
63+
5364
return &Decoder{
5465
s: s,
5566
o: o,
56-
tx: o.Begin(),
67+
tx: tx,
5768

5869
offsetToHash: make(map[int64]core.Hash, 0),
5970
hashToOffset: make(map[core.Hash]int64, 0),
6071
crcs: make(map[core.Hash]uint32, 0),
61-
}
72+
}, nil
6273
}
6374

6475
// Decode reads a packfile and stores it in the value pointed to by s.
@@ -76,6 +87,10 @@ func (d *Decoder) doDecode() error {
7687
return err
7788
}
7889

90+
if d.o == nil {
91+
return d.readObjects(count)
92+
}
93+
7994
if err := d.readObjects(count); err != nil {
8095
if err := d.tx.Rollback(); err != nil {
8196
return nil
@@ -89,10 +104,19 @@ func (d *Decoder) doDecode() error {
89104

90105
func (d *Decoder) readObjects(count uint32) error {
91106
for i := 0; i < int(count); i++ {
92-
_, err := d.ReadObject()
107+
obj, err := d.ReadObject()
93108
if err != nil {
94109
return err
95110
}
111+
112+
if d.o == nil {
113+
continue
114+
}
115+
116+
if _, err := d.tx.Set(obj); err != nil {
117+
return err
118+
}
119+
96120
}
97121

98122
return nil
@@ -105,7 +129,7 @@ func (d *Decoder) ReadObject() (core.Object, error) {
105129
return nil, err
106130
}
107131

108-
obj := d.o.NewObject()
132+
obj := d.newObject()
109133
obj.SetSize(h.Length)
110134
obj.SetType(h.Type)
111135
var crc uint32
@@ -128,15 +152,23 @@ func (d *Decoder) ReadObject() (core.Object, error) {
128152
d.setOffset(hash, h.Offset)
129153
d.setCRC(hash, crc)
130154

131-
if _, err := d.tx.Set(obj); err != nil {
132-
return nil, err
155+
return obj, nil
156+
}
157+
158+
func (d *Decoder) newObject() core.Object {
159+
if d.o == nil {
160+
return &core.MemoryObject{}
133161
}
134162

135-
return obj, nil
163+
return d.o.NewObject()
136164
}
137165

138166
// ReadObjectAt reads an object at the given location
139167
func (d *Decoder) ReadObjectAt(offset int64) (core.Object, error) {
168+
if !d.s.IsSeekable {
169+
return nil, ErrNonSeekable
170+
}
171+
140172
beforeJump, err := d.s.Seek(offset)
141173
if err != nil {
142174
return nil, err
@@ -204,23 +236,29 @@ func (d *Decoder) setCRC(h core.Hash, crc uint32) {
204236
}
205237

206238
func (d *Decoder) recallByOffset(o int64) (core.Object, error) {
239+
if d.s.IsSeekable {
240+
return d.ReadObjectAt(o)
241+
}
242+
207243
if h, ok := d.offsetToHash[o]; ok {
208244
return d.tx.Get(core.AnyObject, h)
209245
}
210246

211-
return d.ReadObjectAt(o)
247+
return nil, core.ErrObjectNotFound
212248
}
213249

214250
func (d *Decoder) recallByHash(h core.Hash) (core.Object, error) {
251+
if d.s.IsSeekable {
252+
if o, ok := d.hashToOffset[h]; ok {
253+
return d.ReadObjectAt(o)
254+
}
255+
}
256+
215257
obj, err := d.tx.Get(core.AnyObject, h)
216258
if err != core.ErrObjectNotFound {
217259
return obj, err
218260
}
219261

220-
if o, ok := d.hashToOffset[h]; ok {
221-
return d.ReadObjectAt(o)
222-
}
223-
224262
return nil, core.ErrObjectNotFound
225263
}
226264

formats/packfile/decoder_test.go

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,56 +25,72 @@ func (s *ReaderSuite) TestDecode(c *C) {
2525
scanner := NewScanner(f.Packfile())
2626
storage := memory.NewStorage()
2727

28-
d := NewDecoder(scanner, storage.ObjectStorage())
28+
d, err := NewDecoder(scanner, storage.ObjectStorage())
29+
c.Assert(err, IsNil)
2930

3031
ch, err := d.Decode()
3132
c.Assert(err, IsNil)
3233
c.Assert(ch, Equals, f.PackfileHash)
3334

34-
AssertObjects(c, storage, []string{
35-
"918c48b83bd081e863dbe1b80f8998f058cd8294",
36-
"af2d6a6954d532f8ffb47615169c8fdf9d383a1a",
37-
"1669dce138d9b841a518c64b10914d88f5e488ea",
38-
"a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69",
39-
"b8e471f58bcbca63b07bda20e428190409c2db47",
40-
"35e85108805c84807bc66a02d91535e1e24b38b9",
41-
"b029517f6300c2da0f4b651b8642506cd6aaf45d",
42-
"32858aad3c383ed1ff0a0f9bdf231d54a00c9e88",
43-
"d3ff53e0564a9f87d8e84b6e28e5060e517008aa",
44-
"c192bd6a24ea1ab01d78686e417c8bdc7c3d197f",
45-
"d5c0f4ab811897cadf03aec358ae60d21f91c50d",
46-
"49c6bb89b17060d7b4deacb7b338fcc6ea2352a9",
47-
"cf4aa3b38974fb7d81f367c0830f7d78d65ab86b",
48-
"9dea2395f5403188298c1dabe8bdafe562c491e3",
49-
"586af567d0bb5e771e49bdd9434f5e0fb76d25fa",
50-
"9a48f23120e880dfbe41f7c9b7b708e9ee62a492",
51-
"5a877e6a906a2743ad6e45d99c1793642aaf8eda",
52-
"c8f1d8c61f9da76f4cb49fd86322b6e685dba956",
53-
"a8d315b2b1c615d43042c3a62402b8a54288cf5c",
54-
"a39771a7651f97faf5c72e08224d857fc35133db",
55-
"880cd14280f4b9b6ed3986d6671f907d7cc2a198",
56-
"fb72698cab7617ac416264415f13224dfd7a165e",
57-
"4d081c50e250fa32ea8b1313cf8bb7c2ad7627fd",
58-
"eba74343e2f15d62adedfd8c883ee0262b5c8021",
59-
"c2d30fa8ef288618f65f6eed6e168e0d514886f4",
60-
"8dcef98b1d52143e1e2dbc458ffe38f925786bf2",
61-
"aa9b383c260e1d05fbbf6b30a02914555e20c725",
62-
"6ecf0ef2c2dffb796033e5a02219af86ec6584e5",
63-
"dbd3641b371024f44d0e469a9c8f5457b0660de1",
64-
"e8d3ffab552895c19b9fcf7aa264d277cde33881",
65-
"7e59600739c96546163833214c36459e324bad0a",
66-
})
35+
AssertObjects(c, storage, expectedHashes)
36+
})
37+
}
6738

39+
func (s *ReaderSuite) TestDecodeInMemory(c *C) {
40+
fixtures.Basic().Test(c, func(f *fixtures.Fixture) {
41+
scanner := NewScanner(f.Packfile())
42+
d, err := NewDecoder(scanner, nil)
43+
c.Assert(err, IsNil)
44+
45+
ch, err := d.Decode()
46+
c.Assert(err, IsNil)
47+
c.Assert(ch, Equals, f.PackfileHash)
6848
})
6949
}
50+
51+
var expectedHashes = []string{
52+
"918c48b83bd081e863dbe1b80f8998f058cd8294",
53+
"af2d6a6954d532f8ffb47615169c8fdf9d383a1a",
54+
"1669dce138d9b841a518c64b10914d88f5e488ea",
55+
"a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69",
56+
"b8e471f58bcbca63b07bda20e428190409c2db47",
57+
"35e85108805c84807bc66a02d91535e1e24b38b9",
58+
"b029517f6300c2da0f4b651b8642506cd6aaf45d",
59+
"32858aad3c383ed1ff0a0f9bdf231d54a00c9e88",
60+
"d3ff53e0564a9f87d8e84b6e28e5060e517008aa",
61+
"c192bd6a24ea1ab01d78686e417c8bdc7c3d197f",
62+
"d5c0f4ab811897cadf03aec358ae60d21f91c50d",
63+
"49c6bb89b17060d7b4deacb7b338fcc6ea2352a9",
64+
"cf4aa3b38974fb7d81f367c0830f7d78d65ab86b",
65+
"9dea2395f5403188298c1dabe8bdafe562c491e3",
66+
"586af567d0bb5e771e49bdd9434f5e0fb76d25fa",
67+
"9a48f23120e880dfbe41f7c9b7b708e9ee62a492",
68+
"5a877e6a906a2743ad6e45d99c1793642aaf8eda",
69+
"c8f1d8c61f9da76f4cb49fd86322b6e685dba956",
70+
"a8d315b2b1c615d43042c3a62402b8a54288cf5c",
71+
"a39771a7651f97faf5c72e08224d857fc35133db",
72+
"880cd14280f4b9b6ed3986d6671f907d7cc2a198",
73+
"fb72698cab7617ac416264415f13224dfd7a165e",
74+
"4d081c50e250fa32ea8b1313cf8bb7c2ad7627fd",
75+
"eba74343e2f15d62adedfd8c883ee0262b5c8021",
76+
"c2d30fa8ef288618f65f6eed6e168e0d514886f4",
77+
"8dcef98b1d52143e1e2dbc458ffe38f925786bf2",
78+
"aa9b383c260e1d05fbbf6b30a02914555e20c725",
79+
"6ecf0ef2c2dffb796033e5a02219af86ec6584e5",
80+
"dbd3641b371024f44d0e469a9c8f5457b0660de1",
81+
"e8d3ffab552895c19b9fcf7aa264d277cde33881",
82+
"7e59600739c96546163833214c36459e324bad0a",
83+
}
84+
7085
func (s *ReaderSuite) TestDecodeCRCs(c *C) {
7186
f := fixtures.Basic().ByTag("ofs-delta").One()
7287

7388
scanner := NewScanner(f.Packfile())
7489
storage := memory.NewStorage()
7590

76-
d := NewDecoder(scanner, storage.ObjectStorage())
77-
_, err := d.Decode()
91+
d, err := NewDecoder(scanner, storage.ObjectStorage())
92+
c.Assert(err, IsNil)
93+
_, err = d.Decode()
7894
c.Assert(err, IsNil)
7995

8096
var sum uint64
@@ -88,9 +104,8 @@ func (s *ReaderSuite) TestDecodeCRCs(c *C) {
88104
func (s *ReaderSuite) TestReadObjectAt(c *C) {
89105
f := fixtures.Basic().One()
90106
scanner := NewScanner(f.Packfile())
91-
storage := memory.NewStorage()
92-
93-
d := NewDecoder(scanner, storage.ObjectStorage())
107+
d, err := NewDecoder(scanner, nil)
108+
c.Assert(err, IsNil)
94109

95110
// when the packfile is ref-delta based, the offsets are required
96111
if f.Is("ref-delta") {

formats/packfile/scanner.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ type Scanner struct {
4949
// is waiting to be read
5050
pendingObject *ObjectHeader
5151
version, objects uint32
52+
53+
// lsSeekable says if this scanner can do Seek or not, to have a Scanner
54+
// seekable a r implementing io.Seeker is required
55+
IsSeekable bool
5256
}
5357

5458
// NewScanner returns a new Scanner based on a reader, if the given reader
@@ -65,7 +69,8 @@ func NewScanner(r io.Reader) *Scanner {
6569
newByteReadSeeker(seeker),
6670
crc,
6771
},
68-
crc: crc,
72+
crc: crc,
73+
IsSeekable: ok,
6974
}
7075
}
7176

remote.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,12 @@ func (r *Remote) updateObjectStorage(reader io.Reader) error {
174174
}
175175

176176
stream := packfile.NewScanner(reader)
177-
d := packfile.NewDecoder(stream, s)
178-
_, err := d.Decode()
177+
d, err := packfile.NewDecoder(stream, s)
178+
if err != nil {
179+
return err
180+
}
181+
182+
_, err = d.Decode()
179183
return err
180184
}
181185

0 commit comments

Comments
 (0)