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

Commit 3dbfb89

Browse files
authoredNov 27, 2018
Merge pull request #1028 from smola/clone-regression
repository: fix plain clone error handling regression
2 parents f62cd8e + 7441885 commit 3dbfb89

File tree

2 files changed

+57
-19
lines changed

2 files changed

+57
-19
lines changed
 

‎repository.go

+14-11
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,9 @@ func PlainClone(path string, isBare bool, o *CloneOptions) (*Repository, error)
342342
// transport operations.
343343
//
344344
// TODO(mcuadros): move isBare to CloneOptions in v5
345+
// TODO(smola): refuse upfront to clone on a non-empty directory in v5, see #1027
345346
func PlainCloneContext(ctx context.Context, path string, isBare bool, o *CloneOptions) (*Repository, error) {
346-
dirExists, err := checkExistsAndIsEmptyDir(path)
347+
cleanup, cleanupParent, err := checkIfCleanupIsNeeded(path)
347348
if err != nil {
348349
return nil, err
349350
}
@@ -355,7 +356,9 @@ func PlainCloneContext(ctx context.Context, path string, isBare bool, o *CloneOp
355356

356357
err = r.clone(ctx, o)
357358
if err != nil && err != ErrRepositoryAlreadyExists {
358-
cleanUpDir(path, !dirExists)
359+
if cleanup {
360+
cleanUpDir(path, cleanupParent)
361+
}
359362
}
360363

361364
return r, err
@@ -369,37 +372,37 @@ func newRepository(s storage.Storer, worktree billy.Filesystem) *Repository {
369372
}
370373
}
371374

372-
func checkExistsAndIsEmptyDir(path string) (exists bool, err error) {
375+
func checkIfCleanupIsNeeded(path string) (cleanup bool, cleanParent bool, err error) {
373376
fi, err := os.Stat(path)
374377
if err != nil {
375378
if os.IsNotExist(err) {
376-
return false, nil
379+
return true, true, nil
377380
}
378381

379-
return false, err
382+
return false, false, err
380383
}
381384

382385
if !fi.IsDir() {
383-
return false, fmt.Errorf("path is not a directory: %s", path)
386+
return false, false, fmt.Errorf("path is not a directory: %s", path)
384387
}
385388

386389
f, err := os.Open(path)
387390
if err != nil {
388-
return false, err
391+
return false, false, err
389392
}
390393

391394
defer ioutil.CheckClose(f, &err)
392395

393396
_, err = f.Readdirnames(1)
394397
if err == io.EOF {
395-
return true, nil
398+
return true, false, nil
396399
}
397400

398401
if err != nil {
399-
return true, err
402+
return false, false, err
400403
}
401404

402-
return true, fmt.Errorf("directory is not empty: %s", path)
405+
return false, false, nil
403406
}
404407

405408
func cleanUpDir(path string, all bool) error {
@@ -425,7 +428,7 @@ func cleanUpDir(path string, all bool) error {
425428
}
426429
}
427430

428-
return nil
431+
return err
429432
}
430433

431434
// Config return the repository config

‎repository_test.go

+43-8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"gopkg.in/src-d/go-git.v4/plumbing/cache"
2222
"gopkg.in/src-d/go-git.v4/plumbing/object"
2323
"gopkg.in/src-d/go-git.v4/plumbing/storer"
24+
"gopkg.in/src-d/go-git.v4/plumbing/transport"
2425
"gopkg.in/src-d/go-git.v4/storage"
2526
"gopkg.in/src-d/go-git.v4/storage/filesystem"
2627
"gopkg.in/src-d/go-git.v4/storage/memory"
@@ -177,11 +178,12 @@ func (s *RepositorySuite) TestCloneContext(c *C) {
177178
ctx, cancel := context.WithCancel(context.Background())
178179
cancel()
179180

180-
_, err := CloneContext(ctx, memory.NewStorage(), nil, &CloneOptions{
181+
r, err := CloneContext(ctx, memory.NewStorage(), nil, &CloneOptions{
181182
URL: s.GetBasicLocalRepositoryURL(),
182183
})
183184

184-
c.Assert(err, NotNil)
185+
c.Assert(r, NotNil)
186+
c.Assert(err, ErrorMatches, ".* context canceled")
185187
}
186188

187189
func (s *RepositorySuite) TestCloneWithTags(c *C) {
@@ -581,7 +583,20 @@ func (s *RepositorySuite) TestPlainCloneWithRemoteName(c *C) {
581583
c.Assert(remote, NotNil)
582584
}
583585

584-
func (s *RepositorySuite) TestPlainCloneContextWithProperParameters(c *C) {
586+
func (s *RepositorySuite) TestPlainCloneOverExistingGitDirectory(c *C) {
587+
tmpDir := c.MkDir()
588+
r, err := PlainInit(tmpDir, false)
589+
c.Assert(r, NotNil)
590+
c.Assert(err, IsNil)
591+
592+
r, err = PlainClone(tmpDir, false, &CloneOptions{
593+
URL: s.GetBasicLocalRepositoryURL(),
594+
})
595+
c.Assert(r, IsNil)
596+
c.Assert(err, Equals, ErrRepositoryAlreadyExists)
597+
}
598+
599+
func (s *RepositorySuite) TestPlainCloneContextCancel(c *C) {
585600
ctx, cancel := context.WithCancel(context.Background())
586601
cancel()
587602

@@ -590,7 +605,7 @@ func (s *RepositorySuite) TestPlainCloneContextWithProperParameters(c *C) {
590605
})
591606

592607
c.Assert(r, NotNil)
593-
c.Assert(err, NotNil)
608+
c.Assert(err, ErrorMatches, ".* context canceled")
594609
}
595610

596611
func (s *RepositorySuite) TestPlainCloneContextNonExistentWithExistentDir(c *C) {
@@ -604,7 +619,7 @@ func (s *RepositorySuite) TestPlainCloneContextNonExistentWithExistentDir(c *C)
604619
URL: "incorrectOnPurpose",
605620
})
606621
c.Assert(r, NotNil)
607-
c.Assert(err, NotNil)
622+
c.Assert(err, Equals, transport.ErrRepositoryNotFound)
608623

609624
_, err = os.Stat(repoDir)
610625
c.Assert(os.IsNotExist(err), Equals, false)
@@ -625,7 +640,7 @@ func (s *RepositorySuite) TestPlainCloneContextNonExistentWithNonExistentDir(c *
625640
URL: "incorrectOnPurpose",
626641
})
627642
c.Assert(r, NotNil)
628-
c.Assert(err, NotNil)
643+
c.Assert(err, Equals, transport.ErrRepositoryNotFound)
629644

630645
_, err = os.Stat(repoDir)
631646
c.Assert(os.IsNotExist(err), Equals, true)
@@ -645,7 +660,7 @@ func (s *RepositorySuite) TestPlainCloneContextNonExistentWithNotDir(c *C) {
645660
URL: "incorrectOnPurpose",
646661
})
647662
c.Assert(r, IsNil)
648-
c.Assert(err, NotNil)
663+
c.Assert(err, ErrorMatches, ".*not a directory.*")
649664

650665
fi, err := os.Stat(repoDir)
651666
c.Assert(err, IsNil)
@@ -668,8 +683,28 @@ func (s *RepositorySuite) TestPlainCloneContextNonExistentWithNotEmptyDir(c *C)
668683
r, err := PlainCloneContext(ctx, repoDirPath, false, &CloneOptions{
669684
URL: "incorrectOnPurpose",
670685
})
686+
c.Assert(r, NotNil)
687+
c.Assert(err, Equals, transport.ErrRepositoryNotFound)
688+
689+
_, err = os.Stat(dummyFile)
690+
c.Assert(err, IsNil)
691+
692+
}
693+
694+
func (s *RepositorySuite) TestPlainCloneContextNonExistingOverExistingGitDirectory(c *C) {
695+
ctx, cancel := context.WithCancel(context.Background())
696+
cancel()
697+
698+
tmpDir := c.MkDir()
699+
r, err := PlainInit(tmpDir, false)
700+
c.Assert(r, NotNil)
701+
c.Assert(err, IsNil)
702+
703+
r, err = PlainCloneContext(ctx, tmpDir, false, &CloneOptions{
704+
URL: "incorrectOnPurpose",
705+
})
671706
c.Assert(r, IsNil)
672-
c.Assert(err, NotNil)
707+
c.Assert(err, Equals, ErrRepositoryAlreadyExists)
673708
}
674709

675710
func (s *RepositorySuite) TestPlainCloneWithRecurseSubmodules(c *C) {

0 commit comments

Comments
 (0)
This repository has been archived.