Skip to content

Commit a04ddf5

Browse files
author
John Cai
committed
Support v3 index
Currently the index encoder does not support the v3 index format. This change adds support to the encoder. This helps to unlock sparse checkout.
1 parent 3211a7a commit a04ddf5

File tree

2 files changed

+46
-14
lines changed

2 files changed

+46
-14
lines changed

Diff for: plumbing/format/index/encoder.go

+25-9
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414

1515
var (
1616
// EncodeVersionSupported is the range of supported index versions
17-
EncodeVersionSupported uint32 = 2
17+
EncodeVersionSupported uint32 = 3
1818

1919
// ErrInvalidTimestamp is returned by Encode if a Index with a Entry with
2020
// negative timestamp values
@@ -36,9 +36,9 @@ func NewEncoder(w io.Writer) *Encoder {
3636

3737
// Encode writes the Index to the stream of the encoder.
3838
func (e *Encoder) Encode(idx *Index) error {
39-
// TODO: support versions v3 and v4
39+
// TODO: support v4
4040
// TODO: support extensions
41-
if idx.Version != EncodeVersionSupported {
41+
if idx.Version > EncodeVersionSupported {
4242
return ErrUnsupportedVersion
4343
}
4444

@@ -68,8 +68,12 @@ func (e *Encoder) encodeEntries(idx *Index) error {
6868
if err := e.encodeEntry(entry); err != nil {
6969
return err
7070
}
71+
entryLength := entryHeaderLength
72+
if entry.IntentToAdd || entry.SkipWorktree {
73+
entryLength += 2
74+
}
7175

72-
wrote := entryHeaderLength + len(entry.Name)
76+
wrote := entryLength + len(entry.Name)
7377
if err := e.padEntry(wrote); err != nil {
7478
return err
7579
}
@@ -79,10 +83,6 @@ func (e *Encoder) encodeEntries(idx *Index) error {
7983
}
8084

8185
func (e *Encoder) encodeEntry(entry *Entry) error {
82-
if entry.IntentToAdd || entry.SkipWorktree {
83-
return ErrUnsupportedVersion
84-
}
85-
8686
sec, nsec, err := e.timeToUint32(&entry.CreatedAt)
8787
if err != nil {
8888
return err
@@ -110,9 +110,25 @@ func (e *Encoder) encodeEntry(entry *Entry) error {
110110
entry.GID,
111111
entry.Size,
112112
entry.Hash[:],
113-
flags,
114113
}
115114

115+
flagsFlow := []interface{}{flags}
116+
117+
if entry.IntentToAdd || entry.SkipWorktree {
118+
var extendedFlags uint16
119+
120+
if entry.IntentToAdd {
121+
extendedFlags |= intentToAddMask
122+
}
123+
if entry.SkipWorktree {
124+
extendedFlags |= skipWorkTreeMask
125+
}
126+
127+
flagsFlow = []interface{}{flags | entryExtended, extendedFlags}
128+
}
129+
130+
flow = append(flow, flagsFlow...)
131+
116132
if err := binary.Write(e.w, flow...); err != nil {
117133
return err
118134
}

Diff for: plumbing/format/index/encoder_test.go

+21-5
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func (s *IndexSuite) TestEncode(c *C) {
5757
}
5858

5959
func (s *IndexSuite) TestEncodeUnsupportedVersion(c *C) {
60-
idx := &Index{Version: 3}
60+
idx := &Index{Version: 4}
6161

6262
buf := bytes.NewBuffer(nil)
6363
e := NewEncoder(buf)
@@ -67,24 +67,40 @@ func (s *IndexSuite) TestEncodeUnsupportedVersion(c *C) {
6767

6868
func (s *IndexSuite) TestEncodeWithIntentToAddUnsupportedVersion(c *C) {
6969
idx := &Index{
70-
Version: 2,
70+
Version: 3,
7171
Entries: []*Entry{{IntentToAdd: true}},
7272
}
7373

7474
buf := bytes.NewBuffer(nil)
7575
e := NewEncoder(buf)
7676
err := e.Encode(idx)
77-
c.Assert(err, Equals, ErrUnsupportedVersion)
77+
c.Assert(err, IsNil)
78+
79+
output := &Index{}
80+
d := NewDecoder(buf)
81+
err = d.Decode(output)
82+
c.Assert(err, IsNil)
83+
84+
c.Assert(cmp.Equal(idx, output), Equals, true)
85+
c.Assert(output.Entries[0].IntentToAdd, Equals, true)
7886
}
7987

8088
func (s *IndexSuite) TestEncodeWithSkipWorktreeUnsupportedVersion(c *C) {
8189
idx := &Index{
82-
Version: 2,
90+
Version: 3,
8391
Entries: []*Entry{{SkipWorktree: true}},
8492
}
8593

8694
buf := bytes.NewBuffer(nil)
8795
e := NewEncoder(buf)
8896
err := e.Encode(idx)
89-
c.Assert(err, Equals, ErrUnsupportedVersion)
97+
c.Assert(err, IsNil)
98+
99+
output := &Index{}
100+
d := NewDecoder(buf)
101+
err = d.Decode(output)
102+
c.Assert(err, IsNil)
103+
104+
c.Assert(cmp.Equal(idx, output), Equals, true)
105+
c.Assert(output.Entries[0].SkipWorktree, Equals, true)
90106
}

0 commit comments

Comments
 (0)