Skip to content

Commit 320db9a

Browse files
authored
git: Add support for deepening shallow clones (go-git#311)
1 parent db2bc57 commit 320db9a

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

plumbing/transport/internal/common/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ func (s *session) handleAdvRefDecodeError(err error) error {
233233
// UploadPack performs a request to the server to fetch a packfile. A reader is
234234
// returned with the packfile content. The reader must be closed after reading.
235235
func (s *session) UploadPack(ctx context.Context, req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) {
236-
if req.IsEmpty() {
236+
if req.IsEmpty() && len(req.Shallows) == 0 {
237237
return nil, transport.ErrEmptyUploadPackRequest
238238
}
239239

remote.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,13 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
350350
return nil, err
351351
}
352352

353+
if !req.Depth.IsZero() {
354+
req.Shallows, err = r.s.Shallow()
355+
if err != nil {
356+
return nil, fmt.Errorf("existing checkout is not shallow")
357+
}
358+
}
359+
353360
req.Wants, err = getWants(r.s, refs)
354361
if len(req.Wants) > 0 {
355362
req.Haves, err = getHaves(localRefs, remoteRefs, r.s)
@@ -367,13 +374,43 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
367374
return nil, err
368375
}
369376

377+
if !updated {
378+
updated, err = depthChanged(req.Shallows, r.s)
379+
if err != nil {
380+
return nil, fmt.Errorf("error checking depth change: %v", err)
381+
}
382+
}
383+
370384
if !updated {
371385
return remoteRefs, NoErrAlreadyUpToDate
372386
}
373387

374388
return remoteRefs, nil
375389
}
376390

391+
func depthChanged(before []plumbing.Hash, s storage.Storer) (bool, error) {
392+
after, err := s.Shallow()
393+
if err != nil {
394+
return false, err
395+
}
396+
397+
if len(before) != len(after) {
398+
return true, nil
399+
}
400+
401+
bm := make(map[plumbing.Hash]bool, len(before))
402+
for _, b := range before {
403+
bm[b] = true
404+
}
405+
for _, a := range after {
406+
if _, ok := bm[a]; !ok {
407+
return true, nil
408+
}
409+
}
410+
411+
return false, nil
412+
}
413+
377414
func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.UploadPackSession, error) {
378415
c, ep, err := newClient(url, auth, insecure, cabundle)
379416
if err != nil {
@@ -778,6 +815,11 @@ func doCalculateRefs(
778815
}
779816

780817
func getWants(localStorer storage.Storer, refs memory.ReferenceStorage) ([]plumbing.Hash, error) {
818+
shallow := false
819+
if s, _ := localStorer.Shallow(); len(s) > 0 {
820+
shallow = true
821+
}
822+
781823
wants := map[plumbing.Hash]bool{}
782824
for _, ref := range refs {
783825
hash := ref.Hash()
@@ -786,7 +828,7 @@ func getWants(localStorer storage.Storer, refs memory.ReferenceStorage) ([]plumb
786828
return nil, err
787829
}
788830

789-
if !exists {
831+
if !exists || shallow {
790832
wants[hash] = true
791833
}
792834
}

remote_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,32 @@ func (s *RemoteSuite) TestFetchWithDepth(c *C) {
233233
c.Assert(r.s.(*memory.Storage).Objects, HasLen, 18)
234234
}
235235

236+
func (s *RemoteSuite) TestFetchWithDepthChange(c *C) {
237+
r := NewRemote(memory.NewStorage(), &config.RemoteConfig{
238+
URLs: []string{s.GetBasicLocalRepositoryURL()},
239+
})
240+
241+
s.testFetch(c, r, &FetchOptions{
242+
Depth: 1,
243+
RefSpecs: []config.RefSpec{
244+
config.RefSpec("refs/heads/master:refs/heads/master"),
245+
},
246+
}, []*plumbing.Reference{
247+
plumbing.NewReferenceFromStrings("refs/heads/master", "6ecf0ef2c2dffb796033e5a02219af86ec6584e5"),
248+
})
249+
c.Assert(r.s.(*memory.Storage).Commits, HasLen, 1)
250+
251+
s.testFetch(c, r, &FetchOptions{
252+
Depth: 3,
253+
RefSpecs: []config.RefSpec{
254+
config.RefSpec("refs/heads/master:refs/heads/master"),
255+
},
256+
}, []*plumbing.Reference{
257+
plumbing.NewReferenceFromStrings("refs/heads/master", "6ecf0ef2c2dffb796033e5a02219af86ec6584e5"),
258+
})
259+
c.Assert(r.s.(*memory.Storage).Commits, HasLen, 3)
260+
}
261+
236262
func (s *RemoteSuite) testFetch(c *C, r *Remote, o *FetchOptions, expected []*plumbing.Reference) {
237263
err := r.Fetch(o)
238264
c.Assert(err, IsNil)

0 commit comments

Comments
 (0)