Skip to content

Commit

Permalink
plumbing: protocol, Fix empty repos on Git v2.41+
Browse files Browse the repository at this point in the history
Git v2.41.0 comes with [changes](git/git@933e3a4)
that breaks go-git's assumptions for when detecting empty repositories.

Go-git expects a flush instead of the first hash line. Instead, a dummy capabilities^{}
with zero-id is returned. The change aims to allow for identifying
the object format even when cloning empty
repositories.

Signed-off-by: Paulo Gomes <pjbgf@linux.com>
  • Loading branch information
pjbgf committed Jul 1, 2023
1 parent 35f7e67 commit e8303d1
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
1 change: 1 addition & 0 deletions plumbing/protocol/packp/advrefs_decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ func decodeFirstHash(p *advRefsDecoder) decoderStateFn {
return nil
}

// TODO: Use object-format (when available) for hash size. Git 2.41+
if len(p.line) < hashSize {
p.error("cannot read hash, pkt-line too short")
return nil
Expand Down
10 changes: 10 additions & 0 deletions plumbing/protocol/packp/advrefs_decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,16 @@ func (s *AdvRefsDecodeSuite) TestCaps(c *C) {
{Name: capability.SymRef, Values: []string{"HEAD:refs/heads/master"}},
{Name: capability.Agent, Values: []string{"foo=bar"}},
},
}, {
input: []string{
"0000000000000000000000000000000000000000 capabilities^{}\x00report-status report-status-v2 delete-refs side-band-64k quiet atomic ofs-delta object-format=sha1 agent=git/2.41.0\n",
pktline.FlushString,
},
capabilities: []entry{
{Name: capability.ReportStatus, Values: []string(nil)},
{Name: capability.ObjectFormat, Values: []string{"sha1"}},
{Name: capability.Agent, Values: []string{"git/2.41.0"}},
},
}} {
ar := s.testDecodeOK(c, test.input)
for _, fixCap := range test.capabilities {
Expand Down
11 changes: 11 additions & 0 deletions plumbing/transport/http/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ func advertisedReferences(ctx context.Context, s *session, serviceName string) (
return nil, err
}

// Git 2.41+ returns a zero-id plus capabilities when an empty
// repository is being cloned. This skips the existing logic within
// advrefs_decode.decodeFirstHash, which expects a flush-pkt instead.
//
// This logic aligns with plumbing/transport/internal/common/common.go.
if ar.IsEmpty() &&
// Empty repositories are valid for git-receive-pack.
transport.ReceivePackServiceName != serviceName {
return nil, transport.ErrEmptyRemoteRepository
}

transport.FilterUnsupportedCapabilities(ar.Capabilities)
s.advRefs = ar

Expand Down
9 changes: 5 additions & 4 deletions remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,13 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
return err
}

if err = rs.Error(); err != nil {
return err
if rs != nil {
if err = rs.Error(); err != nil {
return err
}
}

return r.updateRemoteReferenceStorage(req, rs)
return r.updateRemoteReferenceStorage(req)
}

func (r *Remote) useRefDeltas(ar *packp.AdvRefs) bool {
Expand Down Expand Up @@ -347,7 +349,6 @@ func (r *Remote) newReferenceUpdateRequest(

func (r *Remote) updateRemoteReferenceStorage(
req *packp.ReferenceUpdateRequest,
result *packp.ReportStatus,
) error {

for _, spec := range r.c.Fetch {
Expand Down

0 comments on commit e8303d1

Please sign in to comment.