diff --git a/plumbing/format/idxfile/encoder.go b/plumbing/format/idxfile/encoder.go index 40cd96859..ee4019e7a 100644 --- a/plumbing/format/idxfile/encoder.go +++ b/plumbing/format/idxfile/encoder.go @@ -84,7 +84,7 @@ func (e *Encoder) encodeHashes(idx *MemoryIndex, statusChan plumbing.StatusChan) return size, err } size += n - update.ObjectsDone++ + update.ObjectsDone = int(idx.Fanout[k]) statusChan.SendUpdateIfPossible(update) } return size, nil @@ -111,7 +111,7 @@ func (e *Encoder) encodeCRC32(idx *MemoryIndex, statusChan plumbing.StatusChan) } size += n - update.ObjectsDone++ + update.ObjectsDone = int(idx.Fanout[k]) statusChan.SendUpdateIfPossible(update) } @@ -139,7 +139,7 @@ func (e *Encoder) encodeOffsets(idx *MemoryIndex, statusChan plumbing.StatusChan } size += n - update.ObjectsDone++ + update.ObjectsDone = int(idx.Fanout[k]) statusChan.SendUpdateIfPossible(update) } diff --git a/plumbing/format/idxfile/encoder_test.go b/plumbing/format/idxfile/encoder_test.go index 8c3e578f0..c183f22de 100644 --- a/plumbing/format/idxfile/encoder_test.go +++ b/plumbing/format/idxfile/encoder_test.go @@ -4,6 +4,7 @@ import ( "bytes" "io" + "github.com/go-git/go-git/v5/plumbing" . "github.com/go-git/go-git/v5/plumbing/format/idxfile" fixtures "github.com/go-git/go-git-fixtures/v4" @@ -29,3 +30,40 @@ func (s *IdxfileSuite) TestDecodeEncode(c *C) { c.Assert(result.Bytes(), DeepEquals, expected) }) } + +func (s *IdxfileSuite) TestEncodeStatusChanCompletes(c *C) { + f := fixtures.ByTag("packfile").One() + idx := new(MemoryIndex) + err := NewDecoder(f.Idx()).Decode(idx) + c.Assert(err, IsNil) + count, err := idx.Count() + c.Assert(err, IsNil) + occupiedBuckets := 0 + var previous uint32 + for _, cumulative := range idx.Fanout { + if cumulative != previous { + occupiedBuckets++ + previous = cumulative + } + } + c.Assert(int(count) > occupiedBuckets, Equals, true) + + updates := make(chan plumbing.StatusUpdate, 1024) + _, err = NewEncoder(io.Discard).Encode(idx, updates) + c.Assert(err, IsNil) + close(updates) + + last := make(map[plumbing.StatusStage]plumbing.StatusUpdate) + for update := range updates { + last[update.Stage] = update + } + for _, stage := range []plumbing.StatusStage{ + plumbing.StatusIndexHash, + plumbing.StatusIndexCRC, + plumbing.StatusIndexOffset, + } { + update, ok := last[stage] + c.Assert(ok, Equals, true) + c.Assert(update.ObjectsDone, Equals, update.ObjectsTotal) + } +}